﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

Функция НастройкиПодсистемы() Экспорт
	
	Возврат МашиночитаемыеДоверенностиФНСПовтИсп.НастройкиПодсистемы();
	
КонецФункции

// Только для см. ЭлектроннаяПодпись.УстановленныеПодписи.
// 
// Параметры:
//  ПодписанныйОбъект - ОпределяемыйТип.ПодписанныйОбъект
//  ИдентификаторыПодписей - Массив из УникальныйИдентификатор
// 
// Возвращаемое значение:
//  Неопределено, ВыборкаИзРезультатаЗапроса
//
Функция МЧДПодписей(ПодписанныйОбъект, ИдентификаторыПодписей) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ЭлектронныеПодписиМЧД.ИдентификаторПодписи КАК ИдентификаторПодписи,
	|	ЭлектронныеПодписиМЧД.МашиночитаемаяДоверенность КАК МашиночитаемаяДоверенность,
	|	ПРЕДСТАВЛЕНИЕ(ЭлектронныеПодписиМЧД.МашиночитаемаяДоверенность) КАК Представление,
	|	ЭлектронныеПодписиМЧД.ТребуетсяПроверка КАК ТребуетсяПроверка,
	|	ЭлектронныеПодписиМЧД.ДатаПроверки КАК ДатаПроверки,
	|	ЭлектронныеПодписиМЧД.Верна КАК Верна,
	|	ЭлектронныеПодписиМЧД.ПодписантСоответствуетПредставителю КАК ПодписантСоответствуетПредставителю,
	|	ЭлектронныеПодписиМЧД.СовместныеПолномочия КАК СовместныеПолномочия,
	|	ЭлектронныеПодписиМЧД.СовместныеПолномочияВерны КАК СовместныеПолномочияВерны,
	|	ЭлектронныеПодписиМЧД.ПротоколПроверки КАК ПротоколПроверки,
	|	ЭлектронныеПодписиМЧД.СтатусВернаУстановленВручную,
	|	ЭлектронныеПодписиМЧД.УстановившийСтатусВерна
	|ИЗ
	|	РегистрСведений.ЭлектронныеПодписиМЧД КАК ЭлектронныеПодписиМЧД
	|ГДЕ
	|	ЭлектронныеПодписиМЧД.ПодписанныйОбъект = &ПодписанныйОбъект
	|	И ЭлектронныеПодписиМЧД.ИдентификаторПодписи В (&ИдентификаторыПодписей)";
	
	Запрос.УстановитьПараметр("ПодписанныйОбъект", ПодписанныйОбъект);
	Запрос.УстановитьПараметр("ИдентификаторыПодписей", ИдентификаторыПодписей);
	
	Результат = Запрос.Выполнить();
	Если Результат.Пустой() Тогда
		Возврат Неопределено;
	Иначе
		Возврат Результат.Выбрать();
	КонецЕсли;
	
КонецФункции

Процедура ЗаполнитьДанныеМЧДПодписи(СвойстваПодписи, Выборка) Экспорт
	
	Результаты = Новый Массив;
	Пока Выборка.НайтиСледующий(Новый Структура("ИдентификаторПодписи", СвойстваПодписи.ИдентификаторПодписи)) Цикл
		РезультатПроверкиПодписиПоМЧД = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД(
			Выборка.МашиночитаемаяДоверенность);
		ЗаполнитьЗначенияСвойств(РезультатПроверкиПодписиПоМЧД, Выборка);
		РезультатПроверкиПодписиПоМЧД.ПротоколПроверки = Выборка.ПротоколПроверки.Получить();
		Результаты.Добавить(РезультатПроверкиПодписиПоМЧД);
	КонецЦикла;
	Выборка.Сбросить();
	Если Результаты.Количество() > 0 Тогда
		СвойстваПодписи.РезультатПроверкиПодписиПоМЧД = Результаты;
	КонецЕсли;
	
КонецПроцедуры

// Добавить информацию об МЧД в строку электронной подписи.
// 
// Параметры:
//  ЭлектроннаяПодписьФайла - Структура:
//    * РезультатПроверкиПодписиПоМЧД - Массив из см. МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД
// 
Процедура ДобавитьИнформациюМЧД(ЭлектроннаяПодписьФайла, УникальныйИдентификатор) Экспорт
	
	Если ТипЗнч(ЭлектроннаяПодписьФайла.РезультатПроверкиПодписиПоМЧД) = Тип("Структура") Тогда
		МассивРезультатов = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ЭлектроннаяПодписьФайла.РезультатПроверкиПодписиПоМЧД);
	Иначе
		МассивРезультатов = ЭлектроннаяПодписьФайла.РезультатПроверкиПодписиПоМЧД;
	КонецЕсли;
	
	Верна = Истина;
	Массив = Новый Массив;
	
	Для Каждого Результат Из МассивРезультатов Цикл // см. МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД
		
		Проверка = "";
		МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.ТекстПроверкиМЧД(Результат, Верна, Проверка);
		
		Массив.Добавить(СтроковыеФункции.ФорматированнаяСтрока(НСтр("ru = '%1 <a href=%2>%3</a>'"),
			Проверка,
			ПолучитьНавигационнуюСсылку(Результат.МашиночитаемаяДоверенность),
			Результат.Представление));
		Массив.Добавить(Символы.ПС);

	КонецЦикла;
	
	ЭлектроннаяПодписьФайла.Вставить("МашиночитаемаяДоверенность", Новый ФорматированнаяСтрока(Массив));
	ЭлектроннаяПодписьФайла.Вставить("МашиночитаемаяДоверенностьВерна", Верна);
	ЭлектроннаяПодписьФайла.Вставить("РезультатПроверкиПодписиПоМЧД", ПоместитьВоВременноеХранилище(
		ЭлектроннаяПодписьФайла.РезультатПроверкиПодписиПоМЧД, УникальныйИдентификатор));
	
КонецПроцедуры

// Заполнить протокол проверки.
// 
// Параметры:
//  Форма - ФормаКлиентскогоПриложения
//  ГруппаПротоколПроверки - ГруппаФормы
//  РезультатПроверкиПодписиПоМЧД - Строка, Массив, Структура
//
Процедура ЗаполнитьПротоколПроверки(Форма, ГруппаПротоколПроверки, Знач РезультатПроверкиПодписиПоМЧД) Экспорт
	
	Если ТипЗнч(РезультатПроверкиПодписиПоМЧД) = Тип("Строка") Тогда
		РезультатПроверкиПодписиПоМЧД = ПолучитьИзВременногоХранилища(РезультатПроверкиПодписиПоМЧД);
	КонецЕсли;
	
	Если ТипЗнч(РезультатПроверкиПодписиПоМЧД) = Тип("Структура") Тогда
		МассивРезультатов = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(РезультатПроверкиПодписиПоМЧД);
	Иначе
		МассивРезультатов = РезультатПроверкиПодписиПоМЧД;
	КонецЕсли;
	
	ОчередностьВывода = Новый Массив;
	ОчередностьВывода.Добавить("ПроверкаДоверенности");
	ОчередностьВывода.Добавить("ПроверкаПодписанта");
	ОчередностьВывода.Добавить("ПроверкаДокумента");
	ОчередностьВывода.Добавить("ПроверкаПолномочий");
	
	Индекс = 0;
	Для Каждого Результат Из МассивРезультатов Цикл // см. МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД
		
		ПротоколПроверки = Результат.ПротоколПроверки;
		Если Не ЗначениеЗаполнено(ПротоколПроверки) Тогда
			Продолжить;
		КонецЕсли;
		
		Элемент = Форма.Элементы.Добавить("СсылкаНаМЧД" + Индекс, Тип("ДекорацияФормы"), ГруппаПротоколПроверки);
		Элемент.Заголовок = СтроковыеФункции.ФорматированнаяСтрока(НСтр("ru = '<a href=%1>%2</a>'"),
			ПолучитьНавигационнуюСсылку(Результат.МашиночитаемаяДоверенность),
			Результат.Представление);
		Элемент.АвтоМаксимальнаяШирина = Ложь;
		
		ГруппаАвтоматическиеПроверки = Форма.Элементы.Добавить("ГруппаАвтоматическиеПроверки" + Индекс, Тип("ГруппаФормы"), ГруппаПротоколПроверки);
		ГруппаАвтоматическиеПроверки.Вид           = ВидГруппыФормы.ОбычнаяГруппа;
		ГруппаАвтоматическиеПроверки.Группировка   = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
		ГруппаАвтоматическиеПроверки.ОтображатьЗаголовок = Ложь;
		
		ГруппаДругиеПроверки = Форма.Элементы.Добавить("ГруппаДругиеПроверки" + Индекс, Тип("ГруппаФормы"), ГруппаПротоколПроверки);
		ГруппаДругиеПроверки.Вид           = ВидГруппыФормы.ОбычнаяГруппа;
		ГруппаДругиеПроверки.Группировка   = ГруппировкаПодчиненныхЭлементовФормы.Горизонтальная;
		ГруппаДругиеПроверки.ОтображатьЗаголовок = Ложь;
		
		ГруппаДругиеПроверкиСписок = Форма.Элементы.Добавить("ГруппаДругиеПроверкиСписок" + Индекс, Тип("ГруппаФормы"), ГруппаДругиеПроверки);
		ГруппаДругиеПроверкиСписок.Вид           = ВидГруппыФормы.ОбычнаяГруппа;
		ГруппаДругиеПроверкиСписок.Группировка   = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
		ГруппаДругиеПроверкиСписок.ОтображатьЗаголовок = Ложь;
		
		ГруппаДругиеПроверкиКнопка = Форма.Элементы.Добавить("ГруппаДругиеПроверкиКнопка" + Индекс, Тип("ГруппаФормы"), ГруппаДругиеПроверки);
		ГруппаДругиеПроверкиКнопка.Вид           = ВидГруппыФормы.ОбычнаяГруппа;
		ГруппаДругиеПроверкиКнопка.Группировка   = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
		ГруппаДругиеПроверкиКнопка.ОтображатьЗаголовок = Ложь;
		
		Если Результат.ТребуетсяПроверка И Не Результат.СтатусВернаУстановленВручную Тогда
			
			НоваяКоманда = Форма.Команды.Добавить("Подключаемый_КомандаОтметитьВручную" + Индекс);
			НоваяКоманда.Действие = "Подключаемый_КомандаОтметитьВручную";
			НоваяКоманда.Подсказка = НСтр("ru = 'Отметить, что полномочия представителя по доверенности проверены и доверенность соответствует документу.'");
			
			Элемент = Форма.Элементы.Добавить("ОтметитьВручную" + Индекс, Тип("КнопкаФормы"), ГруппаДругиеПроверкиКнопка);
			Элемент.Вид = ВидКнопкиФормы.ОбычнаяКнопка;
			Элемент.Заголовок = НСтр("ru = 'Проверена'");
			Элемент.ИмяКоманды = НоваяКоманда.Имя;
			Элемент.ОтображениеПодсказки = ОтображениеПодсказки.Кнопка;
		
		КонецЕсли;
		
		Для Каждого ПолеВывода Из ОчередностьВывода Цикл
		
			Проверка = ПротоколПроверки.Получить(ПолеВывода);
			Если Проверка = Неопределено Тогда
				Проверка = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД(
					Результат.МашиночитаемаяДоверенность);
			КонецЕсли;
			
			Если ПолеВывода = "ПроверкаДоверенности" Или ПолеВывода = "ПроверкаПодписанта" Тогда
				ГруппаДляВывода = ГруппаАвтоматическиеПроверки;
			Иначе
				ГруппаДляВывода = ГруппаДругиеПроверкиСписок;
			КонецЕсли;
			
			ГруппаПроверка = Форма.Элементы.Добавить("ГруппаПроверка" + ПолеВывода + Индекс, Тип("ГруппаФормы"), ГруппаДляВывода);
			ГруппаПроверка.Вид           = ВидГруппыФормы.ОбычнаяГруппа;
			ГруппаПроверка.Группировка   = ГруппировкаПодчиненныхЭлементовФормы.Вертикальная;
			ГруппаПроверка.ОтображатьЗаголовок = Ложь;
			
			ГруппаПроверкаЗаголовок = Форма.Элементы.Добавить("ГруппаПроверкаЗаголовок" + ПолеВывода + Индекс, Тип("ГруппаФормы"), ГруппаПроверка);
			ГруппаПроверкаЗаголовок.Вид           = ВидГруппыФормы.ОбычнаяГруппа;
			ГруппаПроверкаЗаголовок.Группировка   = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;
			ГруппаПроверкаЗаголовок.ОтображатьЗаголовок = Ложь;
			
			Элемент = Форма.Элементы.Добавить("КартинкаПроверки" + ПолеВывода + Индекс, Тип("ДекорацияФормы"), ГруппаПроверкаЗаголовок);
			Элемент.Вид = ВидДекорацииФормы.Картинка;
			Элемент.Ширина = 2;
			Элемент.Высота = 1;
			
			Если Результат.СтатусВернаУстановленВручную Тогда
				Элемент.Картинка = БиблиотекаКартинок.ПроверкаСертификатаУспех;
			ИначеЕсли Проверка.Верна = Неопределено Тогда
				Элемент.Картинка = БиблиотекаКартинок.ПроверкаСертификатаНеВыполнялась;
			Иначе
				Элемент.Картинка = ?(Проверка.Верна, БиблиотекаКартинок.ПроверкаСертификатаУспех, БиблиотекаКартинок.ПроверкаСертификатаОшибка);
			КонецЕсли;
			
			Элемент = Форма.Элементы.Добавить("ЗаголовокПроверки" + ПолеВывода + Индекс, Тип("ДекорацияФормы"), ГруппаПроверкаЗаголовок);
			Элемент.Вид = ВидДекорацииФормы.Надпись;
			Элемент.АвтоМаксимальнаяШирина = Ложь;
			Элемент.МаксимальнаяШирина = 50;
			
			Если Проверка.Верна <> Истина И ЗначениеЗаполнено(Проверка.ТекстПроверки) И Не Результат.СтатусВернаУстановленВручную Тогда
				
				Элемент.УстановитьДействие("ОбработкаНавигационнойСсылки", "Подключаемый_ОбработкаНавигационнойСсылки");
				Элемент.Заголовок = СтроковыеФункции.ФорматированнаяСтрока("<a href = ""%1"">%2</a>", Проверка.ТекстПроверки, Проверка.ЗаголовокПроверки);
				
				Элемент = Форма.Элементы.Добавить("ТекстПроверки" + ПолеВывода + Индекс, Тип("ДекорацияФормы"), ГруппаПроверка);
				Элемент.Вид = ВидДекорацииФормы.Надпись;
				Элемент.Заголовок = СтроковыеФункции.ФорматированнаяСтрока(Проверка.ТекстПроверки);
				Элемент.АвтоМаксимальнаяШирина = Ложь;
				Элемент.МаксимальнаяШирина = 60;
				
			Иначе
				Элемент.Заголовок = Проверка.ЗаголовокПроверки;
			КонецЕсли;
		
		КонецЦикла;
		
		Индекс = Индекс + 1;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПриЗаполненииРеквизитовОрганизации(Реквизиты) Экспорт
	
	Если Реквизиты.ЭтоФизическоеЛицо = Истина Тогда
		МашиночитаемыеДоверенностиФНСПереопределяемый.ПриЗаполненииРеквизитовФизическогоЛица(Реквизиты.Ссылка, Реквизиты);
	ИначеЕсли Реквизиты.ЭтоКонтрагент = Истина Тогда
		МашиночитаемыеДоверенностиФНСПереопределяемый.ПриЗаполненииРеквизитовКонтрагента(Реквизиты.Ссылка, Реквизиты);
	Иначе
		СтандартнаяОбработка = Истина;
		МашиночитаемыеДоверенностиФНСПереопределяемый.ПриЗаполненииРеквизитовОрганизации(Реквизиты.Ссылка, Реквизиты, СтандартнаяОбработка);
		Если СтандартнаяОбработка Тогда
			ПриЗаполненииРеквизитовОрганизацииМЧД(Реквизиты);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Функция ТекущееЗначениеРеквизита(Реквизит, РеквизитТип, ИмяПараметраФормы = "") Экспорт
	
	Если РеквизитТип = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ОписаниеТипов = Новый ОписаниеТипов(РеквизитТип.ВыгрузитьЗначения());
	Возврат ОписаниеТипов.ПривестиЗначение(Реквизит);
	
КонецФункции

// Используется для инициализации параметра сеанса в рамках механизмов БСП,
// см. ИнтеграцияПодсистемБСП.ПриДобавленииОбработчиковУстановкиПараметровСеанса.
//
Процедура ПриДобавленииОбработчиковУстановкиПараметровСеанса(Обработчики) Экспорт
	
	Обработчики.Вставить("ПараметрыАвторизацииВРаспределенномРеестре", "МашиночитаемыеДоверенностиФНССлужебный.УстановитьПараметрСеансаПараметрыАвторизацииВРаспределенномРеестре");
	
КонецПроцедуры

// см. УправлениеПечатьюПереопределяемый.ПриОпределенииНастроекПечати
Процедура ПриОпределенииНастроекПечати(НастройкиПечати) Экспорт
	
	НастройкиПечати.ОбъектыПечати.Добавить(Справочники.МашиночитаемыеДоверенности);
	
КонецПроцедуры

// См. ОчередьЗаданийПереопределяемый.ПриПолученииСпискаШаблонов.
Процедура ПриПолученииСпискаШаблонов(ШаблоныЗаданий) Экспорт
	
	ШаблоныЗаданий.Добавить(Метаданные.РегламентныеЗадания.ОбновлениеСтатусовМЧД.Имя);
	
КонецПроцедуры

// См. РегламентныеЗаданияПереопределяемый.ПриОпределенииНастроекРегламентныхЗаданий
Процедура ПриОпределенииНастроекРегламентныхЗаданий(Настройки) Экспорт
	
	Зависимость = Настройки.Добавить();
	Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.ОбновлениеСтатусовМЧД;
	Зависимость.РаботаетСВнешнимиРесурсами = Истина;
	
	Зависимость = Настройки.Добавить();
	Зависимость.РегламентноеЗадание = Метаданные.РегламентныеЗадания.ОбновлениеКлассификаторовМЧД;
	Зависимость.ДоступноВМоделиСервиса = Истина;
	Зависимость.ДоступноВАвтономномРабочемМесте = Ложь;
	
КонецПроцедуры

Функция ИмяСобытияЖурналаРегистрации() Экспорт
	Возврат НСтр("ru = 'Машиночитаемые доверенности'", ОбщегоНазначения.КодОсновногоЯзыка());
КонецФункции

// Параметры:
//   ТекущиеДела - см. ТекущиеДелаСервер.ТекущиеДела.
//
Процедура ПриЗаполненииСпискаТекущихДел(ТекущиеДела) Экспорт
	
	Если Пользователи.ЭтоСеансВнешнегоПользователя() Тогда
		Возврат;
	КонецЕсли;
	
	Если Не Пользователи.ЭтоПолноправныйПользователь() И Не ПравоДоступа("Просмотр", Метаданные.Справочники.МашиночитаемыеДоверенности) Тогда
		Возврат;
	КонецЕсли;
	
	МодульТекущиеДелаСервер = ОбщегоНазначения.ОбщийМодуль("ТекущиеДелаСервер");
	
	Разделы = МодульТекущиеДелаСервер.РазделыДляОбъекта(Метаданные.Справочники.МашиночитаемыеДоверенности.ПолноеИмя());
	
	КоличествоДоверенностейСИстекающимСрокомДействия = КоличествоДоверенностейСИстекающимСрокомДействия(); 
	
	Для Каждого Раздел Из Разделы Цикл
		Дело = ТекущиеДела.Добавить ();
		Дело.Идентификатор  = "ДоверенностиСИстекающимСрокомДействия";
		Дело.ЕстьДела       = КоличествоДоверенностейСИстекающимСрокомДействия > 0;
		Дело.Представление  = НСтр("ru = 'Истекает строк действия доверенностей'");
		Дело.Количество     = КоличествоДоверенностейСИстекающимСрокомДействия;
		Дело.Важное         = Ложь;
		Дело.Форма          = "Справочник.МашиночитаемыеДоверенности.ФормаСписка";
		Дело.ПараметрыФормы = Новый Структура("ОтборПоСостоянию", "СИстекающимСрокомДействия");
		Дело.Владелец       = Раздел;
	КонецЦикла;
	
	КоличествоДоверенностейТребующихПодписания = КоличествоДоверенностейТребующихПодписания(); 
	
	Для Каждого Раздел Из Разделы Цикл
		Дело = ТекущиеДела.Добавить ();
		Дело.Идентификатор  = "ДоверенностиОжидающиеПодписания";
		Дело.ЕстьДела       = КоличествоДоверенностейТребующихПодписания > 0;
		Дело.Представление  = НСтр("ru = 'Доверенности ожидают подписания'");
		Дело.Количество     = КоличествоДоверенностейТребующихПодписания;
		Дело.Важное         = Ложь;
		Дело.Форма          = "Справочник.МашиночитаемыеДоверенности.ФормаСписка";
		Дело.ПараметрыФормы = Новый Структура("ОтборПоСостоянию", "ОжидаютПодписания");
		Дело.Владелец       = Раздел;
	КонецЦикла;
	
	КоличествоДоверенностейТребующихВнимания = КоличествоДоверенностейТребующихВнимания(); 
	
	Для Каждого Раздел Из Разделы Цикл
		Дело = ТекущиеДела.Добавить ();
		Дело.Идентификатор  = "ДоверенностиТребующиеВнимания";
		Дело.ЕстьДела       = КоличествоДоверенностейТребующихВнимания > 0;
		Дело.Представление  = НСтр("ru = 'Доверенности требуют внимания'");
		Дело.Количество     = КоличествоДоверенностейТребующихВнимания;
		Дело.Важное         = Ложь;
		Дело.Форма          = "Справочник.МашиночитаемыеДоверенности.ФормаСписка";
		Дело.ПараметрыФормы = Новый Структура("ОтборПоСостоянию", "ТребуютВнимания");
		Дело.Владелец       = Раздел;
	КонецЦикла;
	
КонецПроцедуры

Функция ДатаОкончанияПериодаИстекающихДоверенностей(ДатаОтсчета) Экспорт
	Возврат ДатаОтсчета + 259200;
КонецФункции

// Только для ЭлектроннаяПодпись.УдалитьПодпись
Процедура УдалитьМашиночитаемуюДоверенностьПодписи(ПодписанныйОбъект, ИдентификаторПодписи, МашиночитаемаяДоверенность = Неопределено) Экспорт
	
	НаборЗаписей = РегистрыСведений.ЭлектронныеПодписиМЧД.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.ПодписанныйОбъект.Установить(ПодписанныйОбъект);
	НаборЗаписей.Отбор.ИдентификаторПодписи.Установить(ИдентификаторПодписи);
	Если МашиночитаемаяДоверенность <> Неопределено Тогда
		НаборЗаписей.Отбор.МашиночитаемаяДоверенность.Установить(МашиночитаемаяДоверенность);
	КонецЕсли;
	НаборЗаписей.Записать(); // АПК:1327 Блокировка установлена ранее в см. ЭлектроннаяПодпись.УдалитьПодпись

КонецПроцедуры

// Только для ЭлектроннаяПодпись.ДобавитьПодпись
Процедура ДобавитьМашиночитаемуюДоверенностьПодписи(ПодписанныйОбъект, ИдентификаторПодписи, РезультатПроверкиПодписиПоМЧД) Экспорт
	
	Если ТипЗнч(РезультатПроверкиПодписиПоМЧД) = Тип("Структура") Тогда
		МассивРезультатов = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(РезультатПроверкиПодписиПоМЧД);
	Иначе
		МассивРезультатов = РезультатПроверкиПодписиПоМЧД;
	КонецЕсли;
	
	Для Каждого Результат Из МассивРезультатов Цикл
	
		НаборЗаписей = РегистрыСведений.ЭлектронныеПодписиМЧД.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.ПодписанныйОбъект.Установить(ПодписанныйОбъект);
		НаборЗаписей.Отбор.ИдентификаторПодписи.Установить(ИдентификаторПодписи);
		НаборЗаписей.Отбор.МашиночитаемаяДоверенность.Установить(Результат.МашиночитаемаяДоверенность);
		НаборЗаписей.Прочитать();
		НаборЗаписей.Очистить();
		НоваяЗапись = НаборЗаписей.Добавить();
		
		ЗаполнитьЗначенияСвойств(НоваяЗапись, Результат);
		
		Если ЗначениеЗаполнено(Результат.ПротоколПроверки) Тогда
			НоваяЗапись.ПротоколПроверки = Новый ХранилищеЗначения(Результат.ПротоколПроверки);
		КонецЕсли;
		
		НоваяЗапись.ПодписанныйОбъект = ПодписанныйОбъект;
		НоваяЗапись.ИдентификаторПодписи = ИдентификаторПодписи;
		НаборЗаписей.Записать(); // АПК:1327 Блокировка установлена ранее в см. ЭлектроннаяПодпись.ДобавитьПодпись
	
	КонецЦикла;

КонецПроцедуры

// Только для ЭлектроннаяПодпись.ОбновитьПодпись
Процедура ДобавитьБлокировку(Блокировка, ПодписанныйОбъект) Экспорт
	ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ЭлектронныеПодписиМЧД");
	ЭлементБлокировки.УстановитьЗначение("ПодписанныйОбъект", ПодписанныйОбъект);
КонецПроцедуры

// Только для ЭлектроннаяПодпись.ОбновитьПодпись
Процедура ОбновитьМашиночитаемуюДоверенностьПодписи(ПодписанныйОбъект, ИдентификаторПодписи, РезультатПроверкиПодписиПоМЧД) Экспорт
	
	Если ТипЗнч(РезультатПроверкиПодписиПоМЧД) = Тип("Строка") Тогда
		РезультатПроверкиПодписиПоМЧД = ПолучитьИзВременногоХранилища(РезультатПроверкиПодписиПоМЧД);
	КонецЕсли;
	
	Если ТипЗнч(РезультатПроверкиПодписиПоМЧД) = Тип("Структура") Тогда
		МассивРезультатов = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(РезультатПроверкиПодписиПоМЧД);
	Иначе
		МассивРезультатов = РезультатПроверкиПодписиПоМЧД;
	КонецЕсли;
		
	Для Каждого Результат Из МассивРезультатов Цикл
	
		НаборЗаписей = РегистрыСведений.ЭлектронныеПодписиМЧД.СоздатьНаборЗаписей();
		НаборЗаписей.Отбор.ПодписанныйОбъект.Установить(ПодписанныйОбъект);
		НаборЗаписей.Отбор.ИдентификаторПодписи.Установить(ИдентификаторПодписи);
		НаборЗаписей.Отбор.МашиночитаемаяДоверенность.Установить(Результат.МашиночитаемаяДоверенность);
		НаборЗаписей.Прочитать();
		
		Если НаборЗаписей.Количество() = 0 Тогда
			НоваяЗапись = НаборЗаписей.Добавить();
		Иначе
			НоваяЗапись = НаборЗаписей[0];
		КонецЕсли;
		
		ЗаполнитьЗначенияСвойств(НоваяЗапись, Результат);
		
		Если ЗначениеЗаполнено(Результат.ПротоколПроверки) Тогда
			НоваяЗапись.ПротоколПроверки = Новый ХранилищеЗначения(Результат.ПротоколПроверки);
		КонецЕсли;
		
		НоваяЗапись.ПодписанныйОбъект = ПодписанныйОбъект;
		НоваяЗапись.ИдентификаторПодписи = ИдентификаторПодписи;
		НаборЗаписей.Записать(); // АПК:1327 Блокировка установлена ранее в см. ЭлектроннаяПодпись.ОбновитьПодпись
		
	КонецЦикла;

КонецПроцедуры

Функция ТекстЗапросаДляУдаленияЭлектронныхПодписей() Экспорт
	
	Текст =
		"ВЫБРАТЬ
		|	ЭлектронныеПодписи.ПорядковыйНомер КАК ПорядковыйНомер,
		|	ЭлектронныеПодписи.ПодписанныйОбъект КАК ПодписанныйОбъект,
		|	СУММА(ВЫБОР
		|			КОГДА ЕСТЬNULL(ЭлектронныеПодписиМЧД.ПодписанныйОбъект, ИСТИНА) = ИСТИНА
		|				ТОГДА 0
		|			ИНАЧЕ 1
		|		КОНЕЦ) КАК ЕстьПодписиПоМЧД,
		|	ЭлектронныеПодписи.ИдентификаторПодписи КАК ИдентификаторПодписи
		|ИЗ
		|	РегистрСведений.ЭлектронныеПодписи КАК ЭлектронныеПодписи
		|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЭлектронныеПодписиМЧД КАК ЭлектронныеПодписиМЧД
		|		ПО ЭлектронныеПодписи.ПодписанныйОбъект = ЭлектронныеПодписиМЧД.ПодписанныйОбъект
		|			И ЭлектронныеПодписи.ИдентификаторПодписи = ЭлектронныеПодписиМЧД.ИдентификаторПодписи
		|ГДЕ
		|	ЭлектронныеПодписи.ПорядковыйНомер В(&МассивПорядковыхНомеров)
		|	И ЭлектронныеПодписи.ПодписанныйОбъект = &ПодписанныйОбъект
		|
		|СГРУППИРОВАТЬ ПО
		|	ЭлектронныеПодписи.ПорядковыйНомер,
		|	ЭлектронныеПодписи.ПодписанныйОбъект,
		|	ЭлектронныеПодписи.ИдентификаторПодписи
		|
		|УПОРЯДОЧИТЬ ПО
		|	ПорядковыйНомер УБЫВ";
	
	Возврат Текст;
	
КонецФункции

Процедура ПриДобавленииОписанияДополнительныхДанных(ДополнительныеДанные, ОписаниеФайлов, Сведения, Текст) Экспорт
	
	ДоверенностиМЧД = Новый Массив;

	Если ДополнительныеДанные.Свойство("ДоверенностьМЧД") Тогда
		ДоверенностиМЧД = ДополнительныеДанные.ДоверенностьМЧД;
	КонецЕсли;
	
	Если ДоверенностиМЧД = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(ДоверенностиМЧД) <> Тип("Массив") Тогда
		ДоверенностиМЧД = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(ДоверенностиМЧД);
	КонецЕсли;
	
	Для Каждого ДоверенностьМЧД Из ДоверенностиМЧД Цикл
		ДобавитьОписаниеДоверенностиМЧД(ДоверенностьМЧД, ОписаниеФайлов, Текст);
	КонецЦикла;
	
КонецПроцедуры

Процедура ПриСозданииНаСервере(Форма) Экспорт
	
	Если Форма.Элементы.Найти("ОткрытьМашиночитаемыеДоверенности") = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если (Пользователи.ЭтоПолноправныйПользователь() Или ПравоДоступа("Просмотр", Метаданные.Справочники.МашиночитаемыеДоверенности)) Тогда
		Форма.Элементы.ОткрытьМашиночитаемыеДоверенности.Видимость = Истина;
		Форма.Элементы.ОткрытьМашиночитаемыеДоверенности.Заголовок = Метаданные.Справочники.МашиночитаемыеДоверенности.Синоним;
	Иначе
		Форма.Элементы.ОткрытьМашиночитаемыеДоверенности.Видимость = Ложь;
	КонецЕсли;
	
КонецПроцедуры

Функция РезультатПроверкиПодписиПоМЧД(Доверенность, ПодписанныйОбъект, Сертификат, НаДату = Неопределено, Знач ГотовыеПроверки = Неопределено) Экспорт
	
	Возврат РезультатПроверкиПодписиПоДаннымМЧД(ДанныеМЧД(Доверенность, ПодписанныйОбъект), Сертификат, НаДату, ГотовыеПроверки);
	
КонецФункции

// Результат проверки подписи по МЧД.
// 
// Параметры:
//  ДанныеМЧД - Структура, ВыборкаИзРезультатаЗапроса:
//   * ПодписанныйОбъект
//   * Представление
//   * ФайлДоверенности
//   * РегистрироватьВРеестре
//   * НомерДоверенности
//   * Статус
//   * Ссылка
//   * Верна
//   * СтатусВернаУстановленВручную
//   * УстановившийСтатусВерна
//   * Полномочия
//   * Ограничения
//   * СовместныеПолномочия
//  Сертификат - см. МашиночитаемыеДоверенностиФНС.ОтборДляДоверенностейПоСертификату.Сертификат
//  НаДату - Неопределено, Дата - если Неопределено, то на дату сеанса.
//  ГотовыеПроверки - Структура - содержит ранее выполненную проверку, которую не надо выполнять заново:
//   * ПроверкаДоверенности
//   * ПроверкаПодписанта
// 
// Возвращаемое значение:
//   см. МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД
// 
Функция РезультатПроверкиПодписиПоДаннымМЧД(ДанныеМЧД, Сертификат, НаДату = Неопределено, Знач ГотовыеПроверки = Неопределено) Экспорт
	
	ПротоколПроверки = Новый Соответствие;
	
	ДатаПроверки = ТекущаяДатаСеанса();
	РезультатПроверкиПодписиПоМЧД = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиПодписиПоМЧД(
		ДанныеМЧД.Ссылка);
	РезультатПроверкиПодписиПоМЧД.Представление = ДанныеМЧД.Представление;
	
	Если ГотовыеПроверки = Неопределено Или ГотовыеПроверки.ПроверкаДоверенности = Неопределено Тогда
		ПроверкаДоверенности = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиДоверенности(
			РезультатПроверкиДанныхДоверенности(ДанныеМЧД));
		ДобавитьВПротоколПроверкуДоверенности(ПротоколПроверки, ПроверкаДоверенности, ДатаПроверки);
	Иначе
		ПротоколПроверки.Вставить("ПроверкаДоверенности", ГотовыеПроверки.ПроверкаДоверенности);
	КонецЕсли;
	
	Если ГотовыеПроверки = Неопределено Или ГотовыеПроверки.ПроверкаПодписанта = Неопределено Тогда
		ПроверкаПодписанта = ПроверитьСертификатПредставителя(ДанныеМЧД.Ссылка, Сертификат, НаДату);
		ДобавитьВПротоколПроверкуПодписанта(ПротоколПроверки, ПроверкаПодписанта, ДатаПроверки);
		ПодписантСоответствуетПредставителю = ПроверкаПодписанта.Результат;
	Иначе
		ПротоколПроверки.Вставить("ПроверкаПодписанта", ГотовыеПроверки.ПроверкаПодписанта);
		ПодписантСоответствуетПредставителю = ГотовыеПроверки.ПроверкаПодписанта.Верна = Истина;
	КонецЕсли;
	
	ПроверкаПолномочий = МашиночитаемыеДоверенностиФНС.РезультатПроверкиДляПротокола();
	ПроверкаПолномочий.ЗаголовокПроверки = НСтр("ru='Проверка полномочий'");
	ПротоколПроверки.Вставить("ПроверкаПолномочий", ПроверкаПолномочий);
	
	ПроверкаДокумента = МашиночитаемыеДоверенностиФНС.РезультатПроверкиДляПротокола();
	ПроверкаДокумента.ЗаголовокПроверки = НСтр("ru='Проверка документа'");
	ПротоколПроверки.Вставить("ПроверкаДокумента", ПроверкаДокумента);
	
	МашиночитаемыеДоверенностиФНСПереопределяемый.ПриПроверкеДоверенностиПодписи(ДанныеМЧД, Сертификат, ПротоколПроверки);

	Верна = Истина;
	ТребуетсяПроверка = Ложь;
	Для Каждого КлючИЗначение Из ПротоколПроверки Цикл
		Если КлючИЗначение.Значение.Верна = Неопределено Тогда
			Верна = Ложь;
			ТребуетсяПроверка = Истина;
			Прервать;
		КонецЕсли;
		Если КлючИЗначение.Значение.Верна = Ложь Тогда
			Верна = Ложь;
			ТребуетсяПроверка = Ложь;
		КонецЕсли;
	КонецЦикла;
	
	Если ПротоколПроверки["ПроверкаДоверенности"].Верна <> Истина
		Или ПротоколПроверки["ПроверкаПодписанта"].Верна <> Истина Тогда
		ТребуетсяПроверка = Ложь;
	КонецЕсли;

	РезультатПроверкиПодписиПоМЧД.Верна = Верна;
	РезультатПроверкиПодписиПоМЧД.ТребуетсяПроверка = ТребуетсяПроверка;
	РезультатПроверкиПодписиПоМЧД.ПротоколПроверки = ПротоколПроверки;
	РезультатПроверкиПодписиПоМЧД.ДатаПроверки = ДатаПроверки;
	РезультатПроверкиПодписиПоМЧД.ПодписантСоответствуетПредставителю = ПодписантСоответствуетПредставителю;
	РезультатПроверкиПодписиПоМЧД.СовместныеПолномочия = ДанныеМЧД.СовместныеПолномочия;

	Возврат РезультатПроверкиПодписиПоМЧД;
	
КонецФункции

// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииСерверныхОповещений
Процедура ПриДобавленииСерверныхОповещений(Оповещения) Экспорт
	
	Оповещение = СерверныеОповещения.НовоеСерверноеОповещение(
		"СтандартныеПодсистемы.МашиночитаемыеДоверенности");
	
	Оповещение.ИмяМодуляОтправки  = "";
	Оповещение.ИмяМодуляПолучения = "МашиночитаемыеДоверенностиФНССлужебныйКлиент";
	
	Оповещения.Вставить(Оповещение.Имя, Оповещение);
	
КонецПроцедуры

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	
	РегистрыСведений.КлассификаторыМЧД.ПриДобавленииОбработчиковОбновления(Обработчики);
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция ПолномочияПоКодам(КодыПолномочий) Экспорт
	
	МассивПолномочий = Новый Массив;
	КлассификаторПолномочий = МашиночитаемыеДоверенностиФНСПовтИсп.КлассификаторПолномочий(); // ДеревоЗначений
	Для Каждого КодПолномочия Из КодыПолномочий Цикл
		Найдено = КлассификаторПолномочий.Строки.Найти(КодПолномочия,"Код", Истина);
		Если Найдено = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		ДобавитьСтрокиПолномочий(Найдено, МассивПолномочий);
	КонецЦикла;
	Возврат МассивПолномочий;
	
КонецФункции

Процедура ДобавитьСтрокиПолномочий(Строка, МассивПолномочий)
	
	Если Строка.Строки.Количество() > 0 Тогда
		Для Каждого Подстрока Из Строка.Строки Цикл
			ДобавитьСтрокиПолномочий(Подстрока, МассивПолномочий)
		КонецЦикла;
		Возврат;
	КонецЕсли;
	МассивПолномочий.Добавить(Новый Структура("Код, Наименование, ИдентификаторПолномочия",
		Строка.Код, Строка.Наименование,Новый УникальныйИдентификатор));
	
КонецПроцедуры

Процедура ДобавитьВПротоколПроверкуДоверенности(ПротоколПроверки, ПроверкаДоверенности, ДатаПроверки) Экспорт
	
	РезультатПроверки = МашиночитаемыеДоверенностиФНС.РезультатПроверкиДляПротокола();
	РезультатПроверки.Верна = ?(ПроверкаДоверенности.ТребуетсяПроверка, Неопределено, ПроверкаДоверенности.Верна);
	РезультатПроверки.ДатаПроверки = ДатаПроверки;
	РезультатПроверки.ТекстПроверки = ПроверкаДоверенности.ТекстОшибки;
	РезультатПроверки.ЗаголовокПроверки = НСтр("ru='Проверка доверенности'");
	ПроверкаДоверенности.Удалить("РезультатыПроверкиПодписей");
	РезультатПроверки.ДополнительныеДанные = ПроверкаДоверенности;
	ПротоколПроверки.Вставить("ПроверкаДоверенности", РезультатПроверки);
	
КонецПроцедуры

Процедура ДобавитьВПротоколПроверкуПодписанта(ПротоколПроверки, ПроверкаПодписанта, ДатаПроверки) Экспорт
	
	РезультатПроверки = МашиночитаемыеДоверенностиФНС.РезультатПроверкиДляПротокола();
	РезультатПроверки.ДатаПроверки = ДатаПроверки;
	РезультатПроверки.Верна = ПроверкаПодписанта.Результат;
	РезультатПроверки.ТекстПроверки = ПроверкаПодписанта.ТекстОшибки;
	РезультатПроверки.ЗаголовокПроверки = НСтр("ru='Проверка подписанта'");
	ПротоколПроверки.Вставить("ПроверкаПодписанта", РезультатПроверки);
	
КонецПроцедуры

Функция РезультатПроверкиДоверенности(Доверенность, ПроверятьВРеестреФНС = Неопределено, ИдентификаторФормы = Неопределено) Экспорт
	
	Результат = РезультатПроверкиДанныхДоверенности(ДанныеМЧД(Доверенность), ПроверятьВРеестреФНС, ИдентификаторФормы);
	Возврат МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РезультатПроверкиДоверенности(Результат);
	
КонецФункции

// Возвращает промежуточный результат проверки данных доверенности, чтобы недостающие проверки подписей можно было
// выполнить на клиенте.
// 
// Параметры:
//  ДанныеДоверенности - ВыборкаИзРезультатаЗапроса - данные доверенности
//  ПроверятьВРеестреФНС - Неопределено, Булево - проверять в реестре ФНС, если Неопределено - будет выполнена проверка,
//      если установлен признак РегистрироватьВРеестре
//  ИдентификаторФормы - Неопределено -  идентификатор формы, если заполнен и не удалось проверить подпись на сервере,
//      в результатах проверки подписи будет заполнен адрес данных файла и подписи для проверки на клиенте.
// 
// Возвращаемое значение:
//  Структура -  результат проверки данных доверенности:
//   * СтатусВернаУстановленВручную - Булево
//   * УстановившийСтатусВерна - СправочникСсылка.Пользователи
//   * ЕстьВРеестреФНС - Булево
//   * ОшибкаПроверкиВРеестреФНС - Строка
//   * Статус - ПеречислениеСсылка.СтатусыМЧД
//   * РезультатПроверкиПодписей - Массив из Структура
//   * ВыполненаПроверкаПодписей - см. СтатусВернаИзДанныхДоверенности.
//   * СтатусВернаИзДанныхДоверенности - Булево - статус Верна, записанный в базу.
//   * ДатаПроверкиИзДанныхДоверенности - Дата - дата проверки доверенности из базы.
//
Функция РезультатПроверкиДанныхДоверенности(ДанныеДоверенности, ПроверятьВРеестреФНС = Неопределено, ИдентификаторФормы = Неопределено) Экспорт
	
	РезультатПроверкиДоверенности = Новый Структура;
	
	// Если проверяем из формы доверенности, не учитываем признак проверки вручную.
	РезультатПроверкиДоверенности.Вставить("СтатусВернаУстановленВручную", ИдентификаторФормы = Неопределено
		И ДанныеДоверенности.Верна И ДанныеДоверенности.СтатусВернаУстановленВручную);
	
	РезультатПроверкиДоверенности.Вставить("УстановившийСтатусВерна");
	Если РезультатПроверкиДоверенности.СтатусВернаУстановленВручную Тогда
		РезультатПроверкиДоверенности.УстановившийСтатусВерна = ДанныеДоверенности.УстановившийСтатусВерна;
	КонецЕсли;
		
	РезультатПроверкиДоверенности.Вставить("ЕстьВРеестреФНС");
	РезультатПроверкиДоверенности.Вставить("ОшибкаПроверкиВРеестреФНС");
	РезультатПроверкиДоверенности.Вставить("Статус");
	РезультатПроверкиДоверенности.Вставить("РезультатПроверкиПодписей");
	РезультатПроверкиДоверенности.Вставить("ВыполненаПроверкаПодписей", Ложь);
	РезультатПроверкиДоверенности.Вставить("СтатусВернаИзДанныхДоверенности",  ДанныеДоверенности.Верна);
	РезультатПроверкиДоверенности.Вставить("ДатаПроверкиИзДанныхДоверенности", ДанныеДоверенности.ДатаПроверки);
	
	Если ПравоДоступа("Чтение", Метаданные.Справочники.МашиночитаемыеДоверенности) Тогда
		РезультатПроверкиДоверенности.ВыполненаПроверкаПодписей = Истина;
		РезультатПроверкиПодписей = РезультатПроверкиПодписейДоверенности(
			ДанныеДоверенности.Ссылка, ДанныеДоверенности.ФайлДоверенности, ИдентификаторФормы);
		РезультатПроверкиДоверенности.РезультатПроверкиПодписей = РезультатПроверкиПодписей;
	КонецЕсли;
		
	Статус = ДанныеДоверенности.Статус;
	
	ЕстьВРеестреФНС = ДанныеДоверенности.РегистрироватьВРеестре;
		
	Если ЗначениеЗаполнено(ДанныеДоверенности.НомерДоверенности)
		И (ПроверятьВРеестреФНС = Истина Или ПроверятьВРеестреФНС = Неопределено И ЕстьВРеестреФНС) Тогда
		РезультатПроверкиВРеестреФНС = ЧастичныеДанныеДоверенностиМЧДРР(
			ДанныеДоверенности.НомерДоверенности,,НСтр("ru='Не удалось проверить доверенность'"));
		Если ЗначениеЗаполнено(РезультатПроверкиВРеестреФНС.СтатусДоверенности) Тогда
			ЕстьВРеестреФНС = Истина;
			ТехническийСтатус = ПолучитьЗначениеСтатуса(РезультатПроверкиВРеестреФНС.СтатусДоверенности);
			Если ЗначениеЗаполнено(ТехническийСтатус) Тогда
				Статус = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РасчетныйСтатусДокумента(ТехническийСтатус, Истина);
			КонецЕсли;
		Иначе
			РезультатПроверкиДоверенности.ОшибкаПроверкиВРеестреФНС = РезультатПроверкиВРеестреФНС.Ошибка.ТекстОшибки;
		КонецЕсли;
	КонецЕсли;
	
	РезультатПроверкиДоверенности.ЕстьВРеестреФНС = ЕстьВРеестреФНС;
	РезультатПроверкиДоверенности.Статус = Статус;
	
	Возврат РезультатПроверкиДоверенности;
	
КонецФункции

Функция ДанныеМЧД(Доверенность, ПодписанныйОбъект = Неопределено) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	МашиночитаемыеДоверенности.ФайлДоверенности КАК ФайлДоверенности,
	|	МашиночитаемыеДоверенности.Статус КАК Статус,
	|	МашиночитаемыеДоверенности.Верна КАК Верна,
	|	МашиночитаемыеДоверенности.НомерДоверенности КАК НомерДоверенности,
	|	МашиночитаемыеДоверенности.СтатусВернаУстановленВручную КАК СтатусВернаУстановленВручную,
	|	МашиночитаемыеДоверенности.УстановившийСтатусВерна КАК УстановившийСтатусВерна,
	|	МашиночитаемыеДоверенности.ДатаПроверки КАК ДатаПроверки,
	|	МашиночитаемыеДоверенности.ДатаОтмены КАК ДатаОтмены,
	|	МашиночитаемыеДоверенности.ТекстПолномочий КАК ТекстПолномочий,
	|	МашиночитаемыеДоверенности.Полномочия.(
	|		Ссылка КАК Ссылка,
	|		НомерСтроки КАК НомерСтроки,
	|		Код КАК Код,
	|		ИдентификаторПолномочия КАК ИдентификаторПолномочия,
	|		Мнемокод КАК Мнемокод,
	|		Наименование КАК Наименование) КАК Полномочия,
	|	МашиночитаемыеДоверенности.Ограничения.(
	|		Ссылка КАК Ссылка,
	|		НомерСтроки КАК НомерСтроки,
	|		ИдентификаторПолномочия КАК ИдентификаторПолномочия,
	|		Код КАК Код,
	|		Наименование КАК Наименование,
	|		НаименованиеЗначения КАК НаименованиеЗначения,
	|		КодЗначения КАК КодЗначения,
	|		ТекстовоеЗначение КАК ТекстовоеЗначение) КАК Ограничения,
	|	МашиночитаемыеДоверенности.ПолномочияВТекстовомВиде КАК ПолномочияВТекстовомВиде,
	|	МашиночитаемыеДоверенности.ПометкаУдаления,
	|	МашиночитаемыеДоверенности.РегистрироватьВРеестре,
	|	МашиночитаемыеДоверенности.СовместныеПолномочия,
	|	ПРЕДСТАВЛЕНИЕ(МашиночитаемыеДоверенности.Ссылка) КАК Представление,
	|	МашиночитаемыеДоверенности.Ссылка,
	|	&ПодписанныйОбъект КАК ПодписанныйОбъект
	|ИЗ
	|	Справочник.МашиночитаемыеДоверенности КАК МашиночитаемыеДоверенности
	|ГДЕ
	|	МашиночитаемыеДоверенности.Ссылка = &Ссылка";
	
	Запрос.УстановитьПараметр("Ссылка", Доверенность);
	Запрос.УстановитьПараметр("ПодписанныйОбъект", ПодписанныйОбъект);
	
	РезультатЗапроса = Запрос.Выполнить();
	
	Выборка = РезультатЗапроса.Выбрать();
	Выборка.Следующий();
	Возврат Выборка;
	
КонецФункции

// Проверить сертификат доверителя.
// 
// Параметры:
//  Доверенность     - СправочникСсылка.МашиночитаемыеДоверенности
//  ФайлДоверенности - СправочникСсылка.МашиночитаемыеДоверенностиПрисоединенныеФайлы
//  Сертификат - СертификатКриптографии
//             - ДвоичныеДанные
//             - Строка
//  ПроверятьДублиПодписей - Булево
//
// 
// Возвращаемое значение:
//  Булево - доверенность подписана всеми доверителями.
//  Строка - ошибка, сертификат не совпадает с доверителями или подпись уже приложена.
//
Функция ПроверитьСертификатДоверителя(Доверенность, ФайлДоверенности, Сертификат, ПроверятьНаличиеИДублиПодписи = Истина) Экспорт
	
	ДанныеДоверенности = ДанныеДоверителей(Доверенность);
	ДанныеДоверенности.Колонки.Добавить("СертификатПодходит", ОбщегоНазначения.ОписаниеТипаЧисло(2));
	Ошибки = Новый Массив;
	
	ОтборПоСертификату = МашиночитаемыеДоверенностиФНС.ОтборДляДоверенностейПоСертификату(Сертификат, "");
	
	Совпадает = Истина;
	Для Каждого Строка Из ДанныеДоверенности Цикл
		
		Если ПроверятьНаличиеИДублиПодписи И Строка.Подписана Тогда
			Возврат НСтр("ru='Доверенность уже подписана, удалите подпись, чтобы добавить снова.'");
		КонецЕсли;
		
		Совпадает = Истина;
		ОшибкиПоСтроке = Новый Массив;
		
		Для Каждого КлючИЗначение Из ОтборПоСертификату Цикл
			
			Ключ = КлючИЗначение.Ключ;
			
			Если Строка[Ключ] <> КлючИЗначение.Значение Тогда
				Совпадает = Ложь;
				ОшибкиПоСтроке.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='%1 %2 <> %3'"),Ключ,
					Строка[Ключ], КлючИЗначение.Значение));
			КонецЕсли;
			
		КонецЦикла;
		
		Если Не Совпадает Тогда
			
			Доверители = Новый Массив;
			Если ЗначениеЗаполнено(Строка.ФИО) Тогда
				Доверители.Добавить(Строка.ФИО);
			КонецЕсли;
			Если ЗначениеЗаполнено(Строка.НаименованиеОрганизации) Тогда
				Доверители.Добавить(Строка.НаименованиеОрганизации);
			КонецЕсли;
			
			Ошибки.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='Не совпадают данные доверителя (%1) и сертификата:
				|%2'"),
				СтрСоединить(Доверители, ", "),
				СтрСоединить(ОшибкиПоСтроке, ", ")));
				
		Иначе
			Строка.СертификатПодходит = 1;
			Прервать;
		КонецЕсли;
		
	КонецЦикла;
	
	Если Не Совпадает Тогда
		ТекстОшибки = СтрСоединить(Ошибки);
		Возврат ТекстОшибки;
	КонецЕсли;
	
	КоличествоДоверителей = ДанныеДоверенности.Количество();
	Если КоличествоДоверителей = 1 Тогда
		Возврат Истина;
	КонецЕсли;
	
	ДанныеДоверенности.Колонки.Добавить("СертификатПодписиПодходит", ОбщегоНазначения.ОписаниеТипаЧисло(2));
	Если ПроверятьНаличиеИДублиПодписи Тогда
		УстановленныеПодписи = ЭлектроннаяПодпись.УстановленныеПодписи(ФайлДоверенности);
			
		Для Каждого Подпись Из УстановленныеПодписи Цикл
			Сертификат = Новый СертификатКриптографии(Подпись.Сертификат.Получить());
			ОтборПоСертификату = МашиночитаемыеДоверенностиФНС.ОтборДляДоверенностейПоСертификату(Сертификат, "");
			ОтборПоСертификату.Вставить("СертификатПодписиПодходит", 0);
			Найдено = ДанныеДоверенности.НайтиСтроки(ОтборПоСертификату);
			Если Найдено.Количество() > 0 Тогда
				Если Найдено[0].СертификатПодходит Тогда
					Возврат НСтр("ru='Доверенность уже подписана аналогичным сертификатом, удалите подпись, чтобы добавить снова.'");
				КонецЕсли;
				Найдено[0].СертификатПодписиПодходит = 1;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ДанныеДоверенности.Свернуть("Подписана", "СертификатПодписиПодходит");
	
	Возврат КоличествоДоверителей = ДанныеДоверенности.СертификатПодписиПодходит + 1;
	
КонецФункции

Функция ДанныеДоверителей(Доверенность)
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.НаименованиеОрганизации КАК НаименованиеОрганизации,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ФИО КАК ФИО,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ИНН КАК ИНН,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ИННФЛ КАК ИННФЛ,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ОГРН КАК ОГРН,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.СНИЛС КАК СНИЛС,
	|	МашиночитаемыеДоверенностиСтатусы.Подписана КАК Подписана
	|ИЗ
	|	РегистрСведений.МашиночитаемыеДоверенностиПредставителиИДоверители КАК МашиночитаемыеДоверенностиПредставителиИДоверители
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МашиночитаемыеДоверенностиСтатусы КАК МашиночитаемыеДоверенностиСтатусы
	|		ПО МашиночитаемыеДоверенностиПредставителиИДоверители.МашиночитаемаяДоверенность = МашиночитаемыеДоверенностиСтатусы.МашиночитаемаяДоверенность
	|ГДЕ
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.МашиночитаемаяДоверенность = &МашиночитаемаяДоверенность
	|	И МашиночитаемыеДоверенностиПредставителиИДоверители.ТипУчастника = ЗНАЧЕНИЕ(Перечисление.ТипыУчастниковМЧД.Доверитель)";
	Запрос.УстановитьПараметр("МашиночитаемаяДоверенность", Доверенность);
	
	Возврат Запрос.Выполнить().Выгрузить();
	
КонецФункции

// Результат проверки подписей доверенности.
// 
// Параметры:
//  Доверенность       - СправочникСсылка.МашиночитаемыеДоверенности
//  ФайлДоверенности   - СправочникСсылка.МашиночитаемыеДоверенностиПрисоединенныеФайлы
//  ИдентификаторФормы - УникальныйИдентификатор - для сохранения во временном хранилище непроверенных подписей для
//                                                 проверки на клиенте.
//
// Возвращаемое значение:
//   Структура:
//   * ЕстьВсеПодписи - Булево
//   * ТекстОшибки - Строка - если ЕстьВсеПодписи = Ложь.
//   * РезультатыПроверкиПодписей - Массив из Структура:
//     ** Верна - Булево
//     ** КомуВыданСертификат - Строка
//     ** ДатаПодписи - Дата
//     ** ИдентификаторПодписи - УникальныйИдентификатор
//     ** ТребуетсяПроверка - Булево
//     ** Соответствует -  Булево - подпись соответствует доверителю.
//     ** ТекстОшибки - Строка
//     ** ТекстОшибкиСоответствия - Строка
//     ** АдресПодписи - Строка - если заполнен параметр ИдентификаторФормы и ТребуетсяПроверка = Истина.
//     ** АдресДанныхДоверенности - Строка  - если заполнен параметр ИдентификаторФормы и ТребуетсяПроверка = Истина.
//     ** РезультатПроверки - Неопределено - если подпись не требовалось проверять или не удалось ее проверить.
//                         - см. ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи
//
Функция РезультатПроверкиПодписейДоверенности(Доверенность, ФайлДоверенности = Неопределено, ИдентификаторФормы = Неопределено) Экспорт
	
	РезультатПроверкиПодписейДоверенности = Новый Структура("ЕстьВсеПодписи, РезультатыПроверкиПодписей, ТекстОшибки", Ложь, Новый Массив, "");
	
	РезультатПроверкиПодписей = Новый Массив;
	
	Если ФайлДоверенности = Неопределено Тогда
		ФайлДоверенности = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Доверенность, "ФайлДоверенности");
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(ФайлДоверенности) Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru='Не заполнен файл доверенности %1'"), Доверенность);
	КонецЕсли;
	
	ДанныеДоверенности = ДанныеДоверителей(Доверенность);
	ДанныеДоверенности.Колонки.Добавить("СертификатПодходит", Новый ОписаниеТипов("Булево"));
	УстановленныеПодписи = ЭлектроннаяПодпись.УстановленныеПодписи(ФайлДоверенности);
	
	ДвоичныеДанные = Неопределено;
	АдресДанныхДоверенности = Неопределено;
	
	Для Каждого ДанныеПодписи Из УстановленныеПодписи Цикл
		
		РезультатПроверкиПодписиДоверенности = Новый Структура;
		РезультатПроверкиПодписиДоверенности.Вставить("ИдентификаторПодписи", ДанныеПодписи.ИдентификаторПодписи);
		РезультатПроверкиПодписиДоверенности.Вставить("КомуВыданСертификат", ДанныеПодписи.КомуВыданСертификат);
		РезультатПроверкиПодписиДоверенности.Вставить("ДатаПодписи", ДанныеПодписи.ДатаПодписи);
		РезультатПроверкиПодписиДоверенности.Вставить("ПодписьВерна", Ложь);
		РезультатПроверкиПодписиДоверенности.Вставить("ТребуетсяПроверка", Ложь);
		РезультатПроверкиПодписиДоверенности.Вставить("Соответствует", Ложь);
		РезультатПроверкиПодписиДоверенности.Вставить("ТекстОшибки", "");
		РезультатПроверкиПодписиДоверенности.Вставить("ТекстОшибкиСоответствия", "");
		РезультатПроверкиПодписиДоверенности.Вставить("РезультатПроверки");
		
		Сертификат = ДанныеПодписи.Сертификат.Получить();
		Если Не ЗначениеЗаполнено(Сертификат) Тогда
			СвойстваПодписи = ЭлектроннаяПодпись.СвойстваПодписи(ДанныеПодписи.Подпись, Истина);
			Если СвойстваПодписи.Успех = Ложь Тогда
				РезультатПроверкиПодписиДоверенности.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='Не удалось извлечь сертификат подписи %1'"), ДанныеПодписи.ПорядковыйНомер);
				РезультатПроверкиПодписей.Добавить(РезультатПроверкиПодписиДоверенности);
				Продолжить;
			КонецЕсли;
			Если Не ЗначениеЗаполнено(СвойстваПодписи.Сертификат) Тогда
				РезультатПроверкиПодписиДоверенности.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='Не удалось извлечь сертификат подписи %1'"), ДанныеПодписи.ПорядковыйНомер);
				РезультатПроверкиПодписей.Добавить(РезультатПроверкиПодписиДоверенности);
				Продолжить;
			КонецЕсли;
			ДанныеПодписи.Сертификат = СвойстваПодписи.Сертификат;
		КонецЕсли;
		
		Если Не ДанныеПодписи.ПодписьВерна И (ДанныеПодписи.ТребуетсяПроверка Или Не ЗначениеЗаполнено(ДанныеПодписи.ДатаПроверкиПодписи)) Тогда
			РезультатПроверкиПодписиДоверенности.ТребуетсяПроверка = Истина;
		Иначе
			РезультатПроверкиПодписиДоверенности.ПодписьВерна = ДанныеПодписи.ПодписьВерна;
		КонецЕсли;
		
		Если ЭлектроннаяПодпись.ПроверятьЭлектронныеПодписиНаСервере() Тогда
			Если ДвоичныеДанные = Неопределено Тогда
				ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(ФайлДоверенности);
			КонецЕсли;
			
			РезультатПроверкиПодписи = ЭлектроннаяПодписьКлиентСервер.РезультатПроверкиПодписи();
			ОписаниеОшибки = "";
			ЭлектроннаяПодпись.ПроверитьПодпись(Неопределено, ДвоичныеДанные, ДанныеПодписи.Подпись,
				ОписаниеОшибки, Неопределено, РезультатПроверкиПодписи);
			
			Если Не РезультатПроверкиПодписи.ТребуетсяПроверка Тогда
				РезультатПроверкиПодписиДоверенности.ТребуетсяПроверка = РезультатПроверкиПодписи.ТребуетсяПроверка;
				РезультатПроверкиПодписиДоверенности.ПодписьВерна = РезультатПроверкиПодписи.Результат = Истина;
				РезультатПроверкиПодписиДоверенности.РезультатПроверки = РезультатПроверкиПодписи;
				РезультатПроверкиПодписиДоверенности.ТекстОшибки = ОписаниеОшибки;
			КонецЕсли;
		КонецЕсли;
		
		Если ИдентификаторФормы <> Неопределено И РезультатПроверкиПодписиДоверенности.ТребуетсяПроверка Тогда
			Если ДвоичныеДанные = Неопределено Тогда
				ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(ФайлДоверенности);
			КонецЕсли;
			Если АдресДанныхДоверенности = Неопределено Тогда
				АдресДанныхДоверенности = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ИдентификаторФормы);
			КонецЕсли;
			РезультатПроверкиПодписиДоверенности.Вставить("АдресДанныхДоверенности", АдресДанныхДоверенности);
			РезультатПроверкиПодписиДоверенности.Вставить("АдресПодписи",
				ПоместитьВоВременноеХранилище(ДанныеПодписи.Подпись, ИдентификаторФормы));
		КонецЕсли;
		
		ОтборПоСертификату = МашиночитаемыеДоверенностиФНС.ОтборДляДоверенностейПоСертификату(Сертификат, "");
		Ошибки = Новый Массив;
		Соответствует = Ложь;
		
		Для Каждого Строка Из ДанныеДоверенности Цикл
			Совпадает = Истина;
			ОшибкиПоСтроке = Новый Массив;
			Для Каждого КлючИЗначение Из ОтборПоСертификату Цикл
				Ключ = КлючИЗначение.Ключ;
				Если Строка[Ключ] <> КлючИЗначение.Значение Тогда
					Совпадает = Ложь;
					ОшибкиПоСтроке.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='%1 %2 <> %3'"), Ключ, Строка[Ключ], КлючИЗначение.Значение));
				КонецЕсли;
			КонецЦикла;

			Если Не Совпадает Тогда
				Доверители = Новый Массив;
				Если ЗначениеЗаполнено(Строка.ФИО) Тогда
					Доверители.Добавить(Строка.ФИО);
				КонецЕсли;
				Если ЗначениеЗаполнено(Строка.НаименованиеОрганизации) Тогда
					Доверители.Добавить(Строка.НаименованиеОрганизации);
				КонецЕсли;
				Ошибки.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru='Не совпадают данные доверителя (%1) и сертификата:
						 |%2'"), СтрСоединить(Доверители, ", "), СтрСоединить(ОшибкиПоСтроке, ", ")));
			Иначе
				Строка.СертификатПодходит = Истина;
				Соответствует = Истина;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		
		РезультатПроверкиПодписиДоверенности.Соответствует = Соответствует;
		Если Не Соответствует Тогда
			РезультатПроверкиПодписиДоверенности.ТекстОшибкиСоответствия = СтрСоединить(Ошибки, ",");
		КонецЕсли;
		
		РезультатПроверкиПодписей.Добавить(РезультатПроверкиПодписиДоверенности);
	КонецЦикла;
	
	Ошибки = Новый Массив;
	Для Каждого Строка Из ДанныеДоверенности Цикл
		Если Не Строка.СертификатПодходит Тогда
			Ошибки.Добавить(Строка.ФИО);
		КонецЕсли;
	КонецЦикла;
	
	РезультатПроверкиПодписейДоверенности.ЕстьВсеПодписи = Ошибки.Количество() = 0;
	Если Не РезультатПроверкиПодписейДоверенности.ЕстьВсеПодписи Тогда
		РезультатПроверкиПодписейДоверенности.ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru='Нет подписей доверителей: %1'"), СтрСоединить(Ошибки, ","));
	КонецЕсли;
	РезультатПроверкиПодписейДоверенности.РезультатыПроверкиПодписей = РезультатПроверкиПодписей;
	
	Возврат РезультатПроверкиПодписейДоверенности;
	
КонецФункции

Функция ПроверитьСертификатПредставителя(Доверенность, Сертификат, Знач НаДату = Неопределено) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	ОтборПоСертификату = МашиночитаемыеДоверенностиФНС.ОтборДляДоверенностейПоСертификату(Сертификат, "");
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.НаименованиеОрганизации КАК НаименованиеОрганизации,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ФИО КАК ФИО,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ИНН КАК ИНН,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ИННФЛ КАК ИННФЛ,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.ОГРН КАК ОГРН,
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.СНИЛС КАК СНИЛС,
	|	МашиночитаемыеДоверенности.Статус КАК Статус,
	|	МашиночитаемыеДоверенности.ПометкаУдаления КАК ПометкаУдаления,
	|	МашиночитаемыеДоверенности.ДатаВыдачи КАК ДатаВыдачи,
	|	МашиночитаемыеДоверенности.ДатаОтмены КАК ДатаОтмены,
	|	КОНЕЦПЕРИОДА(МашиночитаемыеДоверенности.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания
	|ИЗ
	|	РегистрСведений.МашиночитаемыеДоверенностиПредставителиИДоверители КАК МашиночитаемыеДоверенностиПредставителиИДоверители
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.МашиночитаемыеДоверенности КАК МашиночитаемыеДоверенности
	|		ПО МашиночитаемыеДоверенностиПредставителиИДоверители.МашиночитаемаяДоверенность = МашиночитаемыеДоверенности.Ссылка
	|ГДЕ
	|	МашиночитаемыеДоверенностиПредставителиИДоверители.МашиночитаемаяДоверенность = &МашиночитаемаяДоверенность
	|	И МашиночитаемыеДоверенностиПредставителиИДоверители.ТипУчастника = ЗНАЧЕНИЕ(Перечисление.ТипыУчастниковМЧД.Представитель)";
	
	Запрос.УстановитьПараметр("МашиночитаемаяДоверенность", Доверенность);
	
	МассивУсловий = Новый Массив;
	Для Каждого КлючИЗначение Из ОтборПоСертификату Цикл
		Ключ = КлючИЗначение.Ключ;
		МассивУсловий.Добавить("МашиночитаемыеДоверенностиПредставителиИДоверители." + Ключ + " = &" + Ключ);
		Запрос.УстановитьПараметр(Ключ, КлючИЗначение.Значение);
	КонецЦикла;
	
	Запрос.Текст = Запрос.Текст + Символы.ПС + "И " + СтрСоединить(МассивУсловий, Символы.ПС + "И ");
	Результат = Запрос.Выполнить();
	УстановитьПривилегированныйРежим(Ложь);
	
	ТекстОшибки = "";
	Если Результат.Пустой() Тогда
		ТекстОшибки = НСтр("ru='Сертификат не соответствует представителям по доверенности'");
	Иначе
		Выборка = Результат.Выбрать();
		Выборка.Следующий();
		
		Если Выборка.ПометкаУдаления Тогда
			ТекстОшибки = НСтр("ru='Доверенность помечена на удаление'");
		Иначе
			Если Не ЗначениеЗаполнено(НаДату) Тогда
				НаДату = ТекущаяДатаСеанса();
			КонецЕсли;
			Если НаДату > Выборка.ДатаОкончания Тогда
				ТекстОшибки = НСтр("ru='Срок доверенности истек'");
			ИначеЕсли НаДату < Выборка.ДатаВыдачи Тогда
				ТекстОшибки = НСтр("ru='Срок доверенности еще не наступил'");
			ИначеЕсли Выборка.Статус <> Перечисления.СтатусыМЧД.Действует Тогда
				Если Не ЗначениеЗаполнено(Выборка.ДатаОтмены) Тогда
					ТекстОшибки = НСтр("ru='Доверенность не действует'");
				ИначеЕсли НаДату > Выборка.ДатаОтмены Тогда
					ТекстОшибки = НСтр("ru='Доверенность отменена'");
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Результат = Новый Структура;
	Результат.Вставить("Результат", ПустаяСтрока(ТекстОшибки));
	Результат.Вставить("ТекстОшибки", ТекстОшибки);
	
	Возврат Результат;
	
КонецФункции

Процедура ПриЗаполненииРеквизитовОрганизацииМЧД(Реквизиты)
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Организации") Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(Реквизиты.Ссылка) Тогда
		Возврат; // Реквизиты организации нельзя заполнить, если организация не выбрана.
	КонецЕсли;
	
	МодульОрганизацииСервер = ОбщегоНазначения.ОбщийМодуль("ОрганизацииСервер");
	СведенияОбОрганизации = МодульОрганизацииСервер.СведенияОбОрганизации(Реквизиты.Ссылка,, ТекущаяДатаСеанса());
	
	ЭтоИП = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ЭтоИП", Ложь);
	
	Если ЭтоИП Тогда
		
		Реквизиты.ЭтоИндивидуальныйПредприниматель = Истина;
		Реквизиты.НаименованиеПолное = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПНаименование", "");
		Реквизиты.НаименованиеСокращенное = Реквизиты.НаименованиеПолное;
		Реквизиты.ИНН = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИндивидуальныйПредпринимательИНН", "");
		Реквизиты.ОГРН = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ОГРН", "");
		Реквизиты.ЭлектроннаяПочта = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПАдресЭлектроннойПочты", "");
		
		Реквизиты.ЭлектроннаяПочтаЗначение = КонтактнаяИнформацияВJSON(
			Реквизиты.ЭлектроннаяПочта, "АдресЭлектроннойПочты");
			
		Реквизиты.Телефон = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ТелефонОрганизации", "");
		Реквизиты.ТелефонЗначение = КонтактнаяИнформацияВJSON(Реквизиты.Телефон, "Телефон");
		
		Реквизиты.ЛицоБезДоверенности = Неопределено;
		
		РеквизитыЛицаБезДоверенности = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РеквизитыУчастника("ФизическоеЛицо", Неопределено, "ИндивидуальныйПредприниматель");
		ФИО = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ФизическоеЛицоНаименование", "");
		
		Если ЗначениеЗаполнено(ФИО) Тогда
			ФИО = ФизическиеЛицаКлиентСервер.ЧастиИмени(ФИО);
			РеквизитыЛицаБезДоверенности.Фамилия = ФИО.Фамилия;
			РеквизитыЛицаБезДоверенности.Имя = ФИО.Имя;
			РеквизитыЛицаБезДоверенности.Отчество = ФИО.Имя;
		Иначе
			РеквизитыЛицаБезДоверенности.Фамилия = "";
			РеквизитыЛицаБезДоверенности.Имя = "";
			РеквизитыЛицаБезДоверенности.Отчество = "";
		КонецЕсли;
		
		РеквизитыЛицаБезДоверенности.Пол = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ФизическоеЛицоПол", "");
		РеквизитыЛицаБезДоверенности.СтраховойНомерПФР = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИндивидуальныйПредпринимательСНИЛС", "");
		РеквизитыЛицаБезДоверенности.АдресРегистрации = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "АдресРегистрации", "");
		РеквизитыЛицаБезДоверенности.АдресРегистрацииЗначение = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "АдресРегистрацииJSON", "");
		РеквизитыЛицаБезДоверенности.ЭлектроннаяПочта = Реквизиты.ЭлектроннаяПочта;
		РеквизитыЛицаБезДоверенности.ЭлектроннаяПочтаЗначение = Реквизиты.ЭлектроннаяПочтаЗначение;
		
		РеквизитыЛицаБезДоверенности.Телефон = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ДомашнийТелефонФизЛица", "");
		РеквизитыЛицаБезДоверенности.ТелефонЗначение = КонтактнаяИнформацияВJSON(РеквизитыЛицаБезДоверенности.Телефон, "Телефон");
		
		РеквизитыЛицаБезДоверенности.ДатаРождения = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПДатаРождения", "");
		РеквизитыЛицаБезДоверенности.ДокументВид = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПКодУдостоверенияЛичности", "");
		РеквизитыЛицаБезДоверенности.ДокументНомер = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПСерияУдостоверенияЛичности", "")
		 + ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПНомерУдостоверенияЛичности", "");
		РеквизитыЛицаБезДоверенности.ДокументКемВыдан = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПКемВыданУдостоверенияЛичности", "");
		РеквизитыЛицаБезДоверенности.ДокументДатаВыдачи = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПДатаВыдачиУдостоверенияЛичности", "");
		РеквизитыЛицаБезДоверенности.ДокументКодПодразделения = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПКодПодразделенияУдостоверенияЛичности", "");
		РеквизитыЛицаБезДоверенности.ДокументСрокДействия = Дата(1,1,1);
		
		КодСтраны = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПГражданствоКод", "");
		НаименованиеСтраны = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПГражданствоНаименование", "");
		Если ЗначениеЗаполнено(КодСтраны) Или ЗначениеЗаполнено(НаименованиеСтраны) Тогда
			ДанныеСтраныМира = УправлениеКонтактнойИнформацией.ДанныеСтраныМира(КодСтраны, НаименованиеСтраны);
			Если ДанныеСтраныМира <> Неопределено Тогда
				РеквизитыЛицаБезДоверенности.Гражданство = ДанныеСтраныМира.Ссылка;
			КонецЕсли;
		КонецЕсли;
		РеквизитыЛицаБезДоверенности.БезГражданства = Ложь;
		РеквизитыЛицаБезДоверенности.МестоРождения = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИПМестоРождения", "");
		РеквизитыЛицаБезДоверенности.НомерЗаписиЕдиногоРегистраНаселения = "";
		
		Реквизиты.РеквизитыЛицаБезДоверенности = РеквизитыЛицаБезДоверенности;
		
	Иначе
	
		Реквизиты.ИНН = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ИНН", "");
		Реквизиты.НаименованиеПолное = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "НаименованиеПолное", "");
		Реквизиты.НаименованиеСокращенное = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "НаименованиеСокращенное", "");
		Реквизиты.ОГРН = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ОГРН", "");
		Реквизиты.Телефон = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "ТелефонОрганизации", "");
		
		Реквизиты.ТелефонЗначение = КонтактнаяИнформацияВJSON(Реквизиты.Телефон, "Телефон");
		
		Реквизиты.ЮридическийАдрес = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "АдресОрганизации", "");
		Реквизиты.ЮридическийАдресЗначение = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "АдресОрганизацииJSON", "");
		Реквизиты.КПП  = ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СведенияОбОрганизации, "КПП", "");
	
	КонецЕсли;
	
КонецПроцедуры

Функция КонтактнаяИнформацияВJSON(Значение, Тип)
	
	Если ЗначениеЗаполнено(Значение) И ОбщегоНазначения.ПодсистемаСуществует(
		"СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
		МодульУправлениеКонтактнойИнформацией = ОбщегоНазначения.ОбщийМодуль("УправлениеКонтактнойИнформацией");
		Возврат МодульУправлениеКонтактнойИнформацией.КонтактнаяИнформацияВJSON(
				Значение, Перечисления["ТипыКонтактнойИнформации"][Тип]);
	КонецЕсли;
	
	Возврат Неопределено;
	
КонецФункции

Функция ПроверитьСведенияОбОрганизации(Форма, ПолеСообщения = "", ШаблонСообщения = "%1:", СведенияОбОрганизации = Неопределено) Экспорт
	
	Сведения = ?(СведенияОбОрганизации = Неопределено, Форма, СведенияОбОрганизации);
	
	Если Сведения.ЭтоФизическоеЛицо Тогда
		Если Сведения.ЭтоИндивидуальныйПредприниматель Тогда
			Вид = "ИндивидуальныйПредприниматель";
		ИначеЕсли Сведения.ЭтоДолжностноеЛицо Тогда
			Вид = "ДолжностноеЛицо";
		Иначе
			Вид = "ФизическоеЛицо"
		КонецЕсли;
		
		Реквизиты = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РеквизитыФизическогоЛицаСписок(Ложь, Вид);
	Иначе
		Если Сведения.ЭтоИностраннаяОрганизация Тогда
			Вид = "ИностраннаяОрганизация";
		ИначеЕсли Сведения.ЭтоФилиал Тогда
			Вид = "Филиал";
		ИначеЕсли Сведения.ЭтоИндивидуальныйПредприниматель Тогда
			Вид = "ИндивидуальныйПредприниматель";
		Иначе
			Вид = "РоссийскаяОрганизация";
		КонецЕсли;
	
		Реквизиты = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РеквизитыОрганизацииСписок(Ложь, Вид);
	КонецЕсли;
	
	ПроверяемыеРеквизиты = Новый Массив;
	ДобавитьРеквизитыДляПроверки(Форма, ПроверяемыеРеквизиты, Реквизиты, ПолеСообщения, ШаблонСообщения, СведенияОбОрганизации);
	
	Возврат Не ПроверитьЗаполнениеРеквизитов(
		Форма, ПроверяемыеРеквизиты, СведенияОбОрганизации);
	
КонецФункции

Процедура ЗаполнитьТипыЗначения(ТипСтрока, РеквизитТип, Элемент) Экспорт
	
	Если ТипСтрока = "Организация" Тогда
		ОписаниеТипов = ОписаниеТиповОрганизации();
	ИначеЕсли ТипСтрока = "Контрагент" Тогда
		ОписаниеТипов = ОписаниеТиповКонтрагента();
	Иначе
		ОписаниеТипов = ОписаниеТиповФизическогоЛица();
	КонецЕсли;
	
	ЕстьОрганизации = Не ОписаниеТипов.СодержитТип(Тип("Строка"));
	
	Если Не ЕстьОрганизации Тогда
		ОписаниеТипов = Неопределено;
	КонецЕсли;

	РеквизитТип = Неопределено;
	
	Если ТипЗнч(ОписаниеТипов) = Тип("ОписаниеТипов") Тогда
		
		СоставТипов = Новый СписокЗначений;
		Для Каждого Тип Из ОписаниеТипов.Типы() Цикл
			Если ОбщегоНазначения.ЭтоСсылка(Тип) Тогда
				СоставТипов.Добавить(Тип, Строка(Тип));
			КонецЕсли;
		КонецЦикла;
		
		Если СоставТипов.Количество() > 0 Тогда
			СоставТипов.СортироватьПоПредставлению();
			
			Для Каждого ЭлементСписка Из СоставТипов Цикл
				ЭлементСписка.Представление = Метаданные.НайтиПоТипу(ЭлементСписка.Значение).ПолноеИмя();
			КонецЦикла;
			
			РеквизитТип = СоставТипов;
		КонецЕсли;
		
	КонецЕсли;
	
	Элемент.КнопкаВыбора = РеквизитТип <> Неопределено;
	
	Если Элемент.ОтображениеКнопкиВыбора = ОтображениеКнопкиВыбора.ОтображатьВВыпадающемСписке Тогда
		Элемент.КнопкаВыпадающегоСписка = РеквизитТип <> Неопределено;
		Элемент.КнопкаСоздания          = ?(РеквизитТип = Неопределено, Ложь, Неопределено);
		Элемент.ИсторияВыбораПриВводе   = ?(РеквизитТип = Неопределено,
			ИсторияВыбораПриВводе.НеИспользовать, ИсторияВыбораПриВводе.Авто);
	Иначе
		Элемент.ВыбиратьТип = РеквизитТип <> Неопределено И РеквизитТип.Количество() > 1;
	КонецЕсли;
	
КонецПроцедуры

Функция ОписаниеТиповОрганизации()
	
	Возврат Метаданные.ОпределяемыеТипы.Организация.Тип;
	
КонецФункции

Функция ОписаниеТиповКонтрагента()
	
	Возврат Метаданные.ОпределяемыеТипы.Контрагент.Тип;
	
КонецФункции

Функция ОписаниеТиповФизическогоЛица()
	
	Возврат Метаданные.ОпределяемыеТипы.ФизическоеЛицо.Тип;
	
КонецФункции

Функция РеквизитыУчастникаПоСсылке(СторонаМЧД) Экспорт
	
	ТипСсылки = ТипЗнч(СторонаМЧД);
	ТипУчастникаСтрока = Неопределено;
	Если ОписаниеТиповОрганизации().СодержитТип(ТипСсылки) Тогда
		ТипУчастникаСтрока = "Организация";
	ИначеЕсли ОписаниеТиповКонтрагента().СодержитТип(ТипСсылки) Тогда
		ТипУчастникаСтрока = "Контрагент";
	ИначеЕсли ОписаниеТиповФизическогоЛица().СодержитТип(ТипСсылки) Тогда
		ТипУчастникаСтрока = "ФизическоеЛицо";
	КонецЕсли;
	
	Если ТипУчастникаСтрока = Неопределено Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не определен тип участника: %1 (%2)'"), СторонаМЧД, ТипСсылки);
	КонецЕсли;
		
	Реквизиты = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РеквизитыУчастника(
		ТипУчастникаСтрока, СторонаМЧД, Неопределено);
	Реквизиты.Вставить("ТипСсылки", ТипСсылки);
		
	ПриЗаполненииРеквизитовОрганизации(Реквизиты);
	Возврат Реквизиты;
	
КонецФункции

Функция ЗаголовокДекорации(Реквизиты, ИмяЭлементаОрганизация, ТолькоОсновные, ТолькоОбязательные = Ложь, ПоказыватьПерсональныеДанные = Истина) Экспорт

	Результат = СтруктураЗаголовкаДекорации(Реквизиты, ТолькоОсновные, ПоказыватьПерсональныеДанные, ИмяЭлементаОрганизация, ТолькоОбязательные, Ложь);
	
	Если Результат.ЗаголовокДекорацииОшибки.Количество() > 0 Тогда
		Результат.ЗаголовокДекорации.Добавить(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не заполнены: %1'"),
			СтрСоединить(Результат.ЗаголовокДекорацииОшибки, ", ")));
	КонецЕсли;
	
	ЗаголовокДекорацииСтрока = СтрСоединить(Результат.ЗаголовокДекорации, Символы.ПС);
	
	Возврат СтроковыеФункции.ФорматированнаяСтрока(ЗаголовокДекорацииСтрока);
	
КонецФункции

Функция ЗаголовокДекорацииДляТаблицы(Реквизиты, ИмяЭлементаОрганизация, ТолькоОсновные, ТолькоОбязательные = Ложь, ПоказыватьПерсональныеДанные = Истина) Экспорт

	Результат = СтруктураЗаголовкаДекорации(Реквизиты, ТолькоОсновные, ПоказыватьПерсональныеДанные, ИмяЭлементаОрганизация, ТолькоОбязательные, Истина);
	
	ЗаголовокДекорацииСтрока = СтрСоединить(Результат.ЗаголовокДекорации, Символы.ПС);
	
	Структура = Новый Структура("Представление, НеЗаполненыРеквизиты");
	Структура.Представление = СтроковыеФункции.ФорматированнаяСтрока(ЗаголовокДекорацииСтрока);
	Структура.НеЗаполненыРеквизиты = СтроковыеФункции.ФорматированнаяСтрока(СтрСоединить(Результат.ЗаголовокДекорацииОшибки, ", "));
	
	Возврат Структура;
	
КонецФункции

Функция СтруктураЗаголовкаДекорации(Реквизиты, ТолькоОсновные, ПоказыватьПерсональныеДанные, ИмяЭлементаОрганизация, ТолькоОбязательные = Ложь, ДляТаблицы = Ложь)
	
	Если Реквизиты.ЭтоФизическоеЛицо Тогда
		СписокРеквизитов = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РеквизитыФизическогоЛицаСписок(Ложь,
			МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.ОпределитьВидУчастника(Реквизиты));
	Иначе
		СписокРеквизитов = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.РеквизитыОрганизацииСписок(Ложь,
			МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.ОпределитьВидУчастника(Реквизиты));
	КонецЕсли;
	
	ЗаголовокДекорации = Новый Массив;
	ЗаголовокДекорацииОсновныеРеквизиты = Новый Массив;
	ЗаголовокДекорацииНаименование    = Новый Массив;
	ЗаголовокДекорацииКНаименованию   = Новый Массив;
	ЗаголовокДекорацииПаспорт         = Новый Массив;
	ЗаголовокДекорацииАдрес           = Новый Массив;
	ЗаголовокДекорацииДругиеДанные    = Новый Массив;
	ЗаголовокДекорацииОшибки          = Новый Массив;
	НаименованиеДокумента             = "";
	
	Если Не ПоказыватьПерсональныеДанные Тогда
		ПерсональныеДанные = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.ПерсональныеДанные();
	КонецЕсли;
	
	Для Каждого Реквизит Из Реквизиты Цикл
		
		Если Реквизит.Ключ = "ЭтоИндивидуальныйПредприниматель"
			Или Реквизит.Ключ = "ЭтоФизическоеЛицо"
			Или Реквизит.Ключ = "ЭтоКонтрагент"
			Или Реквизит.Ключ = "ЭтоИностраннаяОрганизация"
			Или Реквизит.Ключ = "ЭтоИндивидуальныйПредприниматель"
			Или Реквизит.Ключ = "ЭтоФилиал"
			Или Реквизит.Ключ = "ЭтоДолжностноеЛицо"
			Или Реквизит.Ключ = "ФактическийАдресЗначение"
			Или Реквизит.Ключ = "ТелефонЗначение"
			Или Реквизит.Ключ = "ЭлектроннаяПочтаЗначение"
			Или Реквизит.Ключ = "ЮридическийАдресЗначение"
			Или Реквизит.Ключ = "АдресРегистрацииЗначение"
			Или Реквизит.Ключ = "НаименованиеСокращенное"
			Или Реквизит.Ключ = "ЮридическийАдресВСтранеРегистрацииЗначение" Тогда
			Продолжить;
		КонецЕсли;
		
		Если Реквизиты.ЭтоФизическоеЛицо И Не ПоказыватьПерсональныеДанные И ПерсональныеДанные.Найти(Реквизит.Ключ) <> Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Найдено = СписокРеквизитов.НайтиПоЗначению(Реквизит.Ключ);
		
		Если Найдено <> Неопределено Тогда
			Если Реквизит.Ключ <> "Отчество" И Найдено.Пометка Тогда
				Если ТолькоОбязательные Тогда
					Продолжить;
				КонецЕсли;
				Если Не ЗначениеЗаполнено(Реквизит.Значение) Тогда
					Продолжить;
				КонецЕсли;
			КонецЕсли;
			
			Если Не ЗначениеЗаполнено(Реквизит.Значение) Тогда
				Ошибка = СтрШаблон("<a style=""color: ПоясняющийОшибкуТекст"" href=""%1:%2"">%3</a>", ИмяЭлементаОрганизация, Реквизит.Ключ, Найдено.Представление);
				
				ЗаголовокДекорацииОшибки.Добавить(Ошибка);
				
				Продолжить;
			КонецЕсли;
			
			Если Реквизит.Ключ = "Пол" Тогда
				Значение = ?(Реквизит.Значение = 1, "Мужской", "Женский");
				ЗаголовокДекорацииКНаименованию.Добавить(СтрШаблон("%1: %2", Найдено.Представление, Значение));
				Продолжить;
			ИначеЕсли Реквизит.Ключ = "ДокументВид" Тогда
				НаименованиеДокумента = ?(Реквизит.Значение = "21", НСтр("ru = 'Паспорт'"), НСтр("ru = 'Иной документ'"));
				Продолжить;
			ИначеЕсли ТипЗнч(Реквизит.Значение) = Тип("Дата") Тогда
				Значение = Формат(Реквизит.Значение, "ДЛФ=D");
			Иначе
				Значение = Реквизит.Значение;
			КонецЕсли;
			
			Если Реквизит.Ключ = "НаименованиеПолное" 
				Или Реквизит.Ключ = "ДолжностьЛицаДоверителя"
				Или Реквизит.Ключ = "Фамилия"
				Или Реквизит.Ключ = "Имя"
				Или Реквизит.Ключ = "Отчество" Тогда
				ЗаголовокДекорацииНаименование.Добавить(Значение);
			ИначеЕсли Реквизит.Ключ = "ИНН"
				Или Реквизит.Ключ = "КПП"
				Или Реквизит.Ключ = "ОГРН" Тогда
				ЗаголовокДекорацииОсновныеРеквизиты.Добавить(СтрШаблон("%1: %2", Найдено.Представление, Значение));
			ИначеЕсли Реквизит.Ключ = "Гражданство"
				Или Реквизит.Ключ = "МестоРождения"
				Или Реквизит.Ключ = "ДатаРождения" Тогда
				ЗаголовокДекорацииКНаименованию.Добавить(СтрШаблон("%1: %2", Найдено.Представление, Значение)); 
			ИначеЕсли Реквизит.Ключ = "ФактическийАдрес"
				Или Реквизит.Ключ = "ЮридическийАдрес"
				Или Реквизит.Ключ = "АдресРегистрации"
				Или Реквизит.Ключ = "ЮридическийАдресВСтранеРегистрации" Тогда
				ЗаголовокДекорацииАдрес.Добавить(СтрШаблон("%1: %2", Найдено.Представление, Значение)); 
			ИначеЕсли Реквизит.Ключ = "ДокументНомер"
				Или Реквизит.Ключ = "ДокументКемВыдан"
				Или Реквизит.Ключ = "ДокументДатаВыдачи"
				Или Реквизит.Ключ = "ДокументКодПодразделения"
				Или Реквизит.Ключ = "ДокументСрокДействия" Тогда
				ЗаголовокДекорацииПаспорт.Добавить(СтрШаблон("%1: %2", Найдено.Представление, Значение));
			Иначе
				ЗаголовокДекорацииДругиеДанные.Добавить(СтрШаблон("%1: %2", Найдено.Представление, Значение));
			КонецЕсли;
			
		КонецЕсли;
	КонецЦикла;
	
	Если Не ТолькоОсновные И ЗаголовокДекорацииНаименование.Количество() > 0 Тогда
		ЗаголовокДекорации.Добавить(СтрСоединить(ЗаголовокДекорацииНаименование, " "));
	КонецЕсли;
	Если ЗаголовокДекорацииОсновныеРеквизиты.Количество() > 0 Тогда
		ЗаголовокДекорации.Добавить(СтрСоединить(ЗаголовокДекорацииОсновныеРеквизиты, " "));
	КонецЕсли;
	Если Не ТолькоОсновные И ЗаголовокДекорацииКНаименованию.Количество() > 0 Тогда
		ЗаголовокДекорации.Добавить(СтрСоединить(ЗаголовокДекорацииКНаименованию, ", "));
	КонецЕсли;
	Если Не ТолькоОсновные И ЗаголовокДекорацииПаспорт.Количество() > 0 Тогда
		ЗаголовокДекорацииПаспорт = НаименованиеДокумента + " " + СтрСоединить(ЗаголовокДекорацииПаспорт, ", ");
		ЗаголовокДекорации.Добавить(ЗаголовокДекорацииПаспорт);
	КонецЕсли;
	Если Не ТолькоОсновные И ЗаголовокДекорацииДругиеДанные.Количество() > 0 Тогда
		ЗаголовокДекорации.Добавить(СтрСоединить(ЗаголовокДекорацииДругиеДанные, ", "));
	КонецЕсли;
	Если Не ТолькоОсновные И ЗаголовокДекорацииАдрес.Количество() > 0 Тогда
		ЗаголовокДекорации.Добавить(СтрСоединить(ЗаголовокДекорацииАдрес, Символы.ПС));
	КонецЕсли;
	
	Возврат Новый Структура("ЗаголовокДекорации, ЗаголовокДекорацииОшибки", ЗаголовокДекорации, ЗаголовокДекорацииОшибки);
	
КонецФункции

Процедура ДобавитьРеквизитыДляПроверки(Форма, ПроверяемыеРеквизиты, РеквизитыДляПроверки,
			ПолеСообщения = "", ШаблонСообщения = "%1:", СведенияОбОрганизации = Неопределено) Экспорт
			
	Сведения = ?(СведенияОбОрганизации = Неопределено, Форма, СведенияОбОрганизации);
	
	Для Каждого Реквизит Из РеквизитыДляПроверки Цикл
		
		ИмяРеквизита = Реквизит.Значение;
		
		ПараметрыРеквизитаДляПроверки = Новый Структура;
		ПараметрыРеквизитаДляПроверки.Вставить("Имя", ИмяРеквизита);
		Если ИмяРеквизита = "Телефон"
			Или ИмяРеквизита = "ЮридическийАдрес"
			Или ИмяРеквизита = "ЮридическийАдресВСтранеРегистрации"
			Или ИмяРеквизита = "АдресРегистрации"
			Или ИмяРеквизита = "ФактическийАдрес" Тогда
			ПараметрыРеквизитаДляПроверки.Вставить("Значение", Сведения[ИмяРеквизита + "Значение"]);
		Иначе
			Если СведенияОбОрганизации = Неопределено Тогда
				ПараметрыРеквизитаДляПроверки.Вставить("Значение", Сведения[ИмяРеквизита]);
			Иначе
				ПараметрыРеквизитаДляПроверки.Вставить("Значение", ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(Сведения, ИмяРеквизита));
			КонецЕсли;
		КонецЕсли;
		ПараметрыРеквизитаДляПроверки.Вставить("ПолеСообщения",
			?(ЗначениеЗаполнено(ПолеСообщения), ПолеСообщения, ИмяРеквизита));
		
		Если Реквизит.Пометка Тогда
			ТекстНезаполненного = "";
		Иначе
			ТекстНезаполненного = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				ШаблонСообщения, Реквизит.Представление);
		КонецЕсли;
		ПараметрыРеквизитаДляПроверки.Вставить("ТекстНезаполненного", ТекстНезаполненного);
		ПараметрыРеквизитаДляПроверки.Вставить("ТекстПроверкиЗначения",
			СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонСообщения, Реквизит.Представление));
		
		ПроверяемыеРеквизиты.Добавить(ПараметрыРеквизитаДляПроверки);
		
	КонецЦикла;
	
КонецПроцедуры

Функция ПроверитьЗаполнениеРеквизитов(Форма, Реквизиты, СведенияОбОрганизации = Неопределено) Экспорт
	
	Отказ = Ложь;
	ВидДокумента = "";
	Гражданство = Неопределено;
	БезГражданства = Неопределено;
	
	Сведения = ?(СведенияОбОрганизации = Неопределено, Форма, СведенияОбОрганизации);
	
	Если Сведения.ЭтоФизическоеЛицо Тогда
		ЭтоФЛ = Истина;
		ЭтоИП = Сведения.ЭтоИндивидуальныйПредприниматель;
	Иначе
		ЭтоФЛ = Ложь;
		ЭтоИП = Сведения.ЭтоИндивидуальныйПредприниматель;
	КонецЕсли;
	
	Для Каждого Реквизит Из Реквизиты Цикл
		
		Если Реквизит.Имя = "ДокументВид" Тогда
			ВидДокумента = Реквизит.Значение;
		ИначеЕсли Реквизит.Имя = "ДокументНомер" Тогда
			НомерДокумента = Реквизит;
		ИначеЕсли Реквизит.Имя = "ДокументКодПодразделения" Тогда
			КодПодразделения = Реквизит;
		ИначеЕсли Реквизит.Имя = "Гражданство" Тогда
			Гражданство = Реквизит;
		ИначеЕсли Реквизит.Имя = "БезГражданства" Тогда
			БезГражданства = Реквизит;
		КонецЕсли;
		
		ПроверитьЗаполнениеРеквизита(Форма, Реквизит, Отказ, ЭтоИП, ЭтоФЛ);
		
	КонецЦикла;
	
	Если Гражданство <> Неопределено Тогда
		ТекстОшибки = ОшибкиПроверкиГражданства(Гражданство.Значение, БезГражданства.Значение);
		Если Не ПустаяСтрока(ТекстОшибки) Тогда
			СообщитьПользователю(Форма, ТекстОшибки, Гражданство.ПолеСообщения, Отказ);
		КонецЕсли;
	КонецЕсли;
	
	Если ВидДокумента = "21" Тогда
		
		ТекстОшибки = ОшибкиПроверкиКодаПодразделения(КодПодразделения.Значение);
		Если Не ПустаяСтрока(ТекстОшибки) Тогда
			ТекстОшибки = КодПодразделения.ТекстПроверкиЗначения + " " + ТекстОшибки;
			СообщитьПользователю(Форма, ТекстОшибки, КодПодразделения.ПолеСообщения, Отказ);
		КонецЕсли;
		
		ТекстОшибки = ОшибкиПроверкиНомераПаспорта(НомерДокумента.Значение);
		Если Не ПустаяСтрока(ТекстОшибки) Тогда
			ТекстОшибки = НомерДокумента.ТекстПроверкиЗначения + " " + ТекстОшибки;
			СообщитьПользователю(Форма, ТекстОшибки, НомерДокумента.ПолеСообщения, Отказ);
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Отказ;
	
КонецФункции

Процедура ПроверитьЗаполнениеРеквизита(Форма, Реквизит, Отказ, ЭтоИП, ЭтоФЛ)
	
	ИмяРеквизита = Реквизит.Имя;
	ПолеСообщения = Реквизит.ПолеСообщения;
	ЗначениеРеквизита = Реквизит.Значение;
	
	Если Не ЗначениеЗаполнено(ЗначениеРеквизита) Тогда
		
		Если ЗначениеЗаполнено(Реквизит.ТекстНезаполненного) Тогда
			ТекстОшибки = Реквизит.ТекстНезаполненного + " " + ТекстОшибкиПолеНеЗаполнено();
			СообщитьПользователю(Форма, ТекстОшибки, ПолеСообщения, Отказ);
		КонецЕсли;
		
		Возврат;
		
	КонецЕсли;
	
	ТекстСообщения = "";
	ПродолжитьПриОшибке = Ложь;
	
	Если ИмяРеквизита = "ИНН" Или ИмяРеквизита = "ИННФЛ" Тогда
		РегламентированныеДанныеКлиентСервер.ИННСоответствуетТребованиям(ЗначениеРеквизита,
			Не (ЭтоИП Или ЭтоФЛ), ТекстСообщения);
		ПродолжитьПриОшибке = Истина;
	ИначеЕсли ИмяРеквизита = "КПП" Тогда
		
		РегламентированныеДанныеКлиентСервер.КППСоответствуетТребованиям(ЗначениеРеквизита, ТекстСообщения);
		
	ИначеЕсли ИмяРеквизита = "ОГРН" Тогда
		РегламентированныеДанныеКлиентСервер.ОГРНСоответствуетТребованиям(ЗначениеРеквизита, Не ЭтоИП, ТекстСообщения);
		
	ИначеЕсли ИмяРеквизита = "ЮридическийАдрес"
		  Или ИмяРеквизита = "ФактическийАдрес"
	      Или ИмяРеквизита = "АдресРегистрации" Тогда
		
		ТекстСообщения = ОшибкиПроверкиАдреса(ЗначениеРеквизита);
		Если ПустаяСтрока(ТекстСообщения) Тогда
			ТекстСообщения = ПроверитьАдрес(ЗначениеРеквизита, ЭтоФЛ);
			ПродолжитьПриОшибке = Истина;
		КонецЕсли;
		
	ИначеЕсли ИмяРеквизита = "Телефон" Тогда
		
		ТекстСообщения = ОшибкиПроверкиТелефона(ЗначениеРеквизита);
		
	ИначеЕсли ИмяРеквизита = "СтраховойНомерПФР" Тогда
		РегламентированныеДанныеКлиентСервер.СтраховойНомерПФРСоответствуетТребованиям(
			ЗначениеРеквизита, ТекстСообщения);
		
	ИначеЕсли ИмяРеквизита = "ЭлектроннаяПочта" Тогда
		
		Попытка
			ОбщегоНазначенияКлиентСервер.РазобратьСтрокуСПочтовымиАдресами(ЗначениеРеквизита);
		Исключение
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			ТекстСообщения = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
		КонецПопытки;
		
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(ТекстСообщения) Тогда
		Возврат;
	КонецЕсли;
	
	ТекстыОшибок = СтрРазделить(ТекстСообщения, Символы.ПС + Символы.ВК, Ложь);
	Для Каждого ТекстОшибки Из ТекстыОшибок Цикл
		ТекстОшибки = Реквизит.ТекстПроверкиЗначения + " " + ТекстОшибки;
		СообщитьПользователю(Форма, ТекстОшибки, ПолеСообщения,
			?(ПродолжитьПриОшибке, Неопределено, Отказ));
	КонецЦикла;
	
КонецПроцедуры

Функция ОшибкиПроверкиАдреса(Знач АдресЗначение)
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
		Возврат "";
	КонецЕсли;
	
	МодульРаботаСАдресами = ОбщегоНазначения.ОбщийМодуль("РаботаСАдресами");
	
	ДополнительныеПараметры = Новый Структура("НаименованиеВключаетСокращение, ПроверитьАдрес", Истина, Истина);
	АдресСтруктура = МодульРаботаСАдресами.СведенияОбАдресе(АдресЗначение, ДополнительныеПараметры);
	
	Если АдресСтруктура.РезультатПроверкиАдреса <> "Успех" Тогда
		Возврат АдресСтруктура.ОшибкиПроверкиАдреса;
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

Функция ОшибкиПроверкиТелефона(Знач ТелефонЗначение)
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
		Возврат "";
	КонецЕсли;
	
	МодульУправлениеКонтактнойИнформацией = ОбщегоНазначения.ОбщийМодуль("УправлениеКонтактнойИнформацией");
	
	ТекстСообщения = Новый Массив;
	ТелефонСтруктура = МодульУправлениеКонтактнойИнформацией.СведенияОТелефоне(ТелефонЗначение);
	
	// Проверка, что телефон российский.
	Если СтрЗаменить(ТелефонСтруктура.КодСтраны, "+", "") <> "7" Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Код страны не российский (должен быть ""7"")'"));
	КонецЕсли;
	
	НомерТелефонаБезКодаСтраны = ТелефонСтруктура.КодГорода + ТелефонСтруктура.НомерТелефона;
	
	Если Не ЗначениеЗаполнено(НомерТелефонаБезКодаСтраны) Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Не заполнен номер телефона'"));
		Возврат СтрСоединить(ТекстСообщения, Символы.ПС);
	КонецЕсли;
	
	КодГородаТолькоЦифры = ТолькоЦифры(ТелефонСтруктура.КодГорода);
	Если СтрДлина(КодГородаТолькоЦифры) < 3 Или СтрДлина(КодГородаТолькоЦифры) > 5 Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Код города должен состоять из 3-5 цифр'"));
	КонецЕсли;
	
	Если СтрДлина(ТолькоЦифры(НомерТелефонаБезКодаСтраны)) <> 10 Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Номер телефона с кодом города должен состоять из 10-и цифр'"));
	КонецЕсли;
	
	Если СтрДлина(ТелефонСтруктура.Добавочный) > 6 Тогда
		ТекстСообщения.Добавить(НСтр("ru = 'Добавочный номер телефона не может быть длиннее 6 символов.'"));
	КонецЕсли;
	
	Если ТекстСообщения.Количество() > 0 Тогда
		Возврат СтрСоединить(ТекстСообщения, Символы.ПС);
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

Функция ТелефонДляОтправкиВСервис(ТелефонЗначение) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
		Возврат "";
	КонецЕсли;
	
	МодульУправлениеКонтактнойИнформацией = ОбщегоНазначения.ОбщийМодуль("УправлениеКонтактнойИнформацией");
	ТелефонСтруктура = МодульУправлениеКонтактнойИнформацией.СведенияОТелефоне(ТелефонЗначение);
	
	ТелефонДляСервиса = "+" + СтрЗаменить(ТелефонСтруктура.КодСтраны, "+", "")
		+ "(" + ТолькоЦифры(ТелефонСтруктура.КодГорода) + ")" + ТолькоЦифры(ТелефонСтруктура.НомерТелефона);
		
	Если ЗначениеЗаполнено(ТелефонСтруктура.Добавочный) Тогда
		ТелефонДляСервиса = ТелефонДляСервиса + ", д." + ТелефонСтруктура.Добавочный;
	КонецЕсли;
	
	// Не более 24 символа.
	Возврат ТелефонДляСервиса;
	
КонецФункции

Функция ОшибкиПроверкиКодаПодразделения(КодПодразделения)
	
	Если ПустаяСтрока(КодПодразделения) Тогда
		Возврат НСтр("ru = 'Не указан код подразделения'");
	КонецЕсли;
	
	СтрокаЦифр = СтрЗаменить(СокрЛП(КодПодразделения), "-", "");
	Если СтрДлина(СтрокаЦифр) < 6 Тогда
		Возврат НСтр("ru = 'Код подразделения задан не полностью'");
	КонецЕсли;
	
	Если Не СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(СтрокаЦифр) Тогда
		Возврат НСтр("ru = 'Код подразделения должен состоять только из цифр.'");
	КонецЕсли;
	
	Если СтрокаЦифр = "000000" Тогда
		Возврат НСтр("ru = 'Код подразделения не может быть нулевым.'");
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

Функция ОшибкиПроверкиГражданства(Гражданство, БезГражданства)
	
	Если БезГражданства = Истина Тогда
		Если ЗначениеЗаполнено(Гражданство) Тогда
			Возврат НСтр("ru = 'Указан признак ""Без гражданства"" и заполнено гражданство.'");
		КонецЕсли;
	Иначе
		Если Не ЗначениеЗаполнено(Гражданство) Тогда
			Возврат НСтр("ru = 'Не заполнено гражданство.'");
		КонецЕсли;
		
		Если Не ЗначениеЗаполнено(Гражданство.Код) Тогда
			Возврат СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Не заполнен код страны гражданства %1.'"), Гражданство);
		КонецЕсли;
	КонецЕсли;
	
	Возврат "";
КонецФункции

Функция ОшибкиПроверкиНомераПаспорта(Знач НомерПаспортаРФ)
	
	Если ПустаяСтрока(НомерПаспортаРФ) Тогда
		Возврат "";
	КонецЕсли;
	
	СтрокаЦифр = СтрЗаменить(НомерПаспортаРФ, ",", "");
	СтрокаЦифр = СтрЗаменить(СтрокаЦифр, " ", "");
	
	Если ПустаяСтрока(СтрокаЦифр) Тогда
		Возврат НСтр("ru = 'Номер паспорта не заполнен'");
	КонецЕсли;
	
	Если СтрДлина(СтрокаЦифр) < 10 Тогда
		Возврат НСтр("ru = 'Номер паспорта задан не полностью'");
	КонецЕсли;
	
	Если НЕ СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(СтрокаЦифр) Тогда
		Возврат НСтр("ru = 'Номер паспорта должен состоять только из цифр.'");
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

Функция ТолькоЦифры(Строка)
	
	ДлинаСтроки = СтрДлина(Строка);
	
	ОбработаннаяСтрока = "";
	Для НомерСимвола = 1 По ДлинаСтроки Цикл
		
		Символ = Сред(Строка, НомерСимвола, 1);
		Если Символ >= "0" И Символ <= "9" Тогда
			ОбработаннаяСтрока = ОбработаннаяСтрока + Символ;
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ОбработаннаяСтрока;
	
КонецФункции

Процедура СообщитьПользователю(Форма, ТекстСообщения, Поле, Отказ = Ложь) Экспорт
	
	Сообщение = Новый СообщениеПользователю;
	Сообщение.ИдентификаторНазначения = Форма.УникальныйИдентификатор;
	Сообщение.Текст = ТекстСообщения;
	Сообщение.Поле = Поле;
	Сообщение.Сообщить();
	
	Отказ = Истина;
	
КонецПроцедуры 

Функция ТекстОшибкиПолеНеЗаполнено() Экспорт
	Возврат НСтр("ru = 'Поле не заполнено'");
КонецФункции

Функция ПроверитьАдрес(Адрес, ЭтоФЛ) Экспорт
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтактнаяИнформация") Тогда
		Возврат "";
	КонецЕсли;
	
	Сообщение = "";
	МодульРаботаСАдресами = ОбщегоНазначения.ОбщийМодуль("РаботаСАдресами");
	
	Попытка
		
		ПодробныйИтог = МодульРаботаСАдресами.ПроверитьАдрес(Адрес);
		Если ПодробныйИтог.Результат <> "Корректный" Тогда
			
			Для каждого ЭлементСписка Из ПодробныйИтог.СписокОшибок Цикл
				Сообщение = Сообщение + Символы.ПС + ЭлементСписка.Представление;
			КонецЦикла;
			
			Сообщение = СокрЛП(Сообщение);
			Если Не ЗначениеЗаполнено(Сообщение) Тогда
				Сообщение = НСтр("ru = 'Адрес не заполнен'");
			КонецЕсли;
			Если ЭтоФЛ Тогда
				Сообщение = Сообщение + " (" + НСтр("ru = 'не ошибка, если указан регион и населенный пункт'")+ ")";
			Иначе
				Сообщение = Сообщение + " (" + НСтр("ru = 'не ошибка, если так в ЕГРЮЛ'")+ ")";
			КонецЕсли;
		КонецЕсли;
		
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		Сообщение = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
	КонецПопытки;
	
	Возврат Сообщение;
	
КонецФункции

Процедура ОбновитьКлассификаторыМЧД() Экспорт
	
	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ОбновлениеКлассификаторовМЧД);
	РегистрыСведений.КлассификаторыМЧД.ОбновитьКлассификаторы();
	
КонецПроцедуры

#Область ДанныеДляМоихДел

Функция КоличествоДоверенностейСИстекающимСрокомДействия()
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МашиночитаемыеДоверенности.Ссылка) КАК Количество
	|ИЗ
	|	Справочник.МашиночитаемыеДоверенности КАК МашиночитаемыеДоверенности
	|ГДЕ
	|	КонецПериода(МашиночитаемыеДоверенности.ДатаОкончания, День) МЕЖДУ &ТекущаяДата И &ДатаОкончания
	|	И МашиночитаемыеДоверенности.Статус = &Статус";

	ТекущаяДатаСеанса = КонецДня(ТекущаяДатаСеанса());

	Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса);
	Запрос.УстановитьПараметр("ДатаОкончания", МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.ДатаОкончанияПериодаИстекающихДоверенностей(ТекущаяДатаСеанса));
	Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыМЧД.Действует);

	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();

	Если Выборка.Следующий() Тогда
		Возврат Выборка.Количество;
	Иначе
		Возврат 0;
	КонецЕсли;
КонецФункции

Функция КоличествоДоверенностейТребующихПодписания()
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МашиночитаемыеДоверенности.Ссылка) КАК Количество
	|ИЗ
	|	Справочник.МашиночитаемыеДоверенности КАК МашиночитаемыеДоверенности
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МашиночитаемыеДоверенностиСтатусы КАК МашиночитаемыеДоверенностиСтатусы
	|		ПО (МашиночитаемыеДоверенностиСтатусы.МашиночитаемаяДоверенность = МашиночитаемыеДоверенности.Ссылка)
	|ГДЕ
	|	МашиночитаемыеДоверенности.Статус = &Статус
	|	И НЕ МашиночитаемыеДоверенностиСтатусы.Подписана";

	ТекущаяДатаСеанса = ТекущаяДатаСеанса();

	Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса);
	Запрос.УстановитьПараметр("Статус", Перечисления.СтатусыМЧД.Черновик);

	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();

	Если Выборка.Следующий() Тогда
		Возврат Выборка.Количество;
	Иначе
		Возврат 0;
	КонецЕсли;
КонецФункции

Функция КоличествоДоверенностейТребующихВнимания()
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ
	|	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ МашиночитаемыеДоверенности.Ссылка) КАК Количество
	|ИЗ
	|	Справочник.МашиночитаемыеДоверенности КАК МашиночитаемыеДоверенности
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.МашиночитаемыеДоверенностиСтатусы КАК МашиночитаемыеДоверенностиСтатусы
	|		ПО (МашиночитаемыеДоверенностиСтатусы.МашиночитаемаяДоверенность = МашиночитаемыеДоверенности.Ссылка)
	|ГДЕ
	|	МашиночитаемыеДоверенности.НомерДоверенности <> """"
	|	И МашиночитаемыеДоверенностиСтатусы.ТехническийСтатус В (&Статусы)
	|	И МашиночитаемыеДоверенности.ДатаОкончания > &ТекущаяДата";

	ТекущаяДатаСеанса = ТекущаяДатаСеанса();

	Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса);
	СтатусыТребующиеВнимания = Новый Массив;
	СтатусыТребующиеВнимания.Добавить(Перечисления.ТехническиеСтатусыМЧД.ОшибкаРегистрации);
	СтатусыТребующиеВнимания.Добавить(Перечисления.ТехническиеСтатусыМЧД.Регистрация);
	СтатусыТребующиеВнимания.Добавить(Перечисления.ТехническиеСтатусыМЧД.РегистрацияОтмены);
	Запрос.УстановитьПараметр("Статусы", СтатусыТребующиеВнимания);

	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();

	Если Выборка.Следующий() Тогда
		Возврат Выборка.Количество;
	Иначе
		Возврат 0;
	КонецЕсли;
КонецФункции

#КонецОбласти

Процедура УстановитьУсловноеОформление(Форма) Экспорт
	
	Форма.УсловноеОформление.Элементы.Очистить();
	
	ЭлементУсловногоОформления = Форма.УсловноеОформление.Элементы.Добавить();
	ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	ЭлементОтбора = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(
		Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаПредставительНесколько.ЛицоПредставителя");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	ОформляемоеПоле = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТаблицаПредставительНесколькоЛицоПредставителя");
	
	ЭлементУсловногоОформления = Форма.УсловноеОформление.Элементы.Добавить();
	ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	ЭлементОтбора = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(
		Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаПредставительНесколько.НеЗаполненыРеквизиты");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	ОформляемоеПоле = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТаблицаПредставительНесколькоНеЗаполненыРеквизиты");
	
	ЭлементУсловногоОформления = Форма.УсловноеОформление.Элементы.Добавить();
	ЭлементУсловногоОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
	
	ЭлементОтбора = ЭлементУсловногоОформления.Отбор.Элементы.Добавить(
		Тип("ЭлементОтбораКомпоновкиДанных"));
	ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаПредставительНесколько.НеЗаполненыРеквизитыФЛ");
	ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеЗаполнено;
	
	ОформляемоеПоле = ЭлементУсловногоОформления.Поля.Элементы.Добавить();
	ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТаблицаПредставительНесколькоНеЗаполненыРеквизитыФЛ");
	
КонецПроцедуры

Функция ВидыДокументовУдостоверяющихЛичность() Экспорт
	
	ВидыДокументов = Новый ТаблицаЗначений;
	ВидыДокументов.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка"));
	ВидыДокументов.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
	ВидыДокументов.Колонки.Добавить("Шаблон", Новый ОписаниеТипов("Строка"));
	ВидыДокументов.Колонки.Добавить("Маска", Новый ОписаниеТипов("Строка"));
	
	ТекстовыйДокумент = ПолучитьОбщийМакет("ВидыДокументовУдостоверяющихЛичность");
	
	Для НомерСтроки = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
		Строка = ТекстовыйДокумент.ПолучитьСтроку(НомерСтроки);
		Если Не ЗначениеЗаполнено(Строка) Тогда
			Продолжить;
		КонецЕсли;
		ЧастиСтроки = СтрРазделить(Строка, ";");
		
		ВидДокумента = ВидыДокументов.Добавить();
		ВидДокумента.Код = ЧастиСтроки[0];
		ВидДокумента.Наименование = ЧастиСтроки[1];
		ВидДокумента.Шаблон =  ЧастиСтроки[3];
		
		Маска = ЧастиСтроки[3];
		Если СтрНайти(Маска, "R")
			Или СтрНайти(Маска, "S") Тогда
			Маска = "";
		Иначе
			Маска = СтрЗаменить(Маска, "0", "#");
			Маска = СтрЗаменить(Маска, "Б", "X");
		КонецЕсли;
		
		ВидДокумента.Маска = Маска;
	КонецЦикла;
	
	ВидыДокументов.Сортировать("Наименование");
	
	Возврат ВидыДокументов;
	
КонецФункции

Процедура ДобавитьОписаниеДоверенностиМЧД(ДоверенностьМЧД, ОписаниеФайлов, Сведения)
	
	ОписаниеФайла = Новый Структура;
	ОписаниеФайла.Вставить("Данные", ДоверенностьМЧД.Данные);
	ОписаниеФайла.Вставить("Имя",    ДоверенностьМЧД.Имя);
	
	Сведения = Сведения + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '%1: ""%2""'"), ДоверенностьМЧД.ТипФайла, ДоверенностьМЧД.Имя) + Символы.ПС;
		
	ОписаниеФайлов.Добавить(ОписаниеФайла);
	
КонецПроцедуры

#Область РаботаСРаспределеннымРеестром

Функция СвойстваСервераМЧДРР()
	
	Результат = НастройкиМЧД();
	
	Если ИспользуетсяРежимТестирования() Тогда
		СохраненныеНастройкиМЧД = ХранилищеОбщихНастроек.Загрузить("ДокументооборотСКонтролирующимиОрганами_НастройкиМЧД");
		Если СохраненныеНастройкиМЧД <> Неопределено Тогда
			ЗаполнитьЗначенияСвойств(Результат, СохраненныеНастройкиМЧД);
		КонецЕсли;
		Если Результат.ИспользоватьРасширенияAPI Тогда
			Результат.ЛогинОператора 	= "";
			Результат.ПарольОператора 	= "";
		КонецЕсли;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	URLСервера = Константы.АдресСервисаМЧДРР.Получить();
	УстановитьПривилегированныйРежим(Ложь);
	Если НЕ ЗначениеЗаполнено(URLСервера) Тогда
		URLСервера = "https://1cpoagate.1c.ru/applications/MChD/api/clientpoa";
	КонецЕсли;
	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(URLСервера);
	ЛогинПароль = ?(ЗначениеЗаполнено(СтруктураURI.Логин) ИЛИ ЗначениеЗаполнено(СтруктураURI.Пароль),
		СтруктураURI.Логин + ":" + СтруктураURI.Пароль + "@", "");
	
	Результат.Вставить("АдресСервера", 					СтруктураURI.Схема + "://" + ЛогинПароль + СтруктураURI.ИмяСервера);
	Результат.Вставить("АдресСервераБезАутентификации", СтруктураURI.Схема + "://" + СтруктураURI.ИмяСервера);
	Результат.Вставить("РесурсКорняAPI", 				"/" + СтруктураURI.ПутьНаСервере);
	
	Возврат Результат;
	
КонецФункции

Функция НастройкиМЧД()
	
	Результат = Новый Структура;
	Результат.Вставить("ЛогинОператора", 			"");
	Результат.Вставить("ПарольОператора", 			"");
	Результат.Вставить("ИспользоватьРасширенияAPI", Истина);
	Результат.Вставить("ТестовыйСервер", 			"test");
	
	Возврат Результат;
	
КонецФункции

Функция ТикетАутентификацииИлиДанныеПользователяНаПорталеПоддержки()
	
	УстановитьПривилегированныйРежим(Истина);
	
	ПродолжитьПолучениеТикета = Ложь;
	Если ОбщегоНазначения.ПодсистемаСуществует("ИнтернетПоддержкаПользователей") Тогда
		МодульИнтернетПоддержкаПользователей = ОбщегоНазначения.ОбщийМодуль("ИнтернетПоддержкаПользователей");	
		ПродолжитьПолучениеТикета = МодульИнтернетПоддержкаПользователей.ЗаполненыДанныеАутентификацииПользователяИнтернетПоддержки();
	КонецЕсли;
	
	Если ПродолжитьПолучениеТикета Тогда
			
			ВладелецТикета = ВладелецТикета();
			
			РезультатПолученияТикета =
				МодульИнтернетПоддержкаПользователей.ТикетАутентификацииНаПорталеПоддержки(ВладелецТикета);
			
			Если РезультатПолученияТикета = Неопределено ИЛИ НЕ ЗначениеЗаполнено(РезультатПолученияТикета.Тикет) Тогда
				Возврат МодульИнтернетПоддержкаПользователей.ДанныеАутентификацииПользователяИнтернетПоддержки();
			
			Иначе
				Возврат РезультатПолученияТикета;
			КонецЕсли;
			
	Иначе
		Возврат Неопределено;
	КонецЕсли;
	
КонецФункции

Функция ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ТекстОшибки) Экспорт 
	Результат = Новый Структура;
	Результат.Вставить("ЗаголовокОшибки", ЗаголовокОшибки);
	Результат.Вставить("ТекстОшибки", ТекстОшибки);
	Результат.Вставить("ЗапросHTTP");
	Результат.Вставить("ОтветHTTP");
	Результат.Вставить("СтруктураОтвета");
	Результат.Вставить("ДополнительныеФайлы");
	Результат.Вставить("ПараметрыТекстаОшибки", Новый Структура);
	Возврат Результат;
КонецФункции 

Функция ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибки) Экспорт
	ЗаголовокОшибки = ПараметрыОшибки.ЗаголовокОшибки;
	ЗапросHTTP = ПараметрыОшибки.ЗапросHTTP;
	ПараметрыТекстаОшибки = ПараметрыОшибки.ПараметрыТекстаОшибки;
	ОтветHTTP = ПараметрыОшибки.ОтветHTTP;
	ТекстОшибки = ПараметрыОшибки.ТекстОшибки;
	СтруктураОтвета = ПараметрыОшибки.СтруктураОтвета;
	ДополнительныеФайлы = ПараметрыОшибки.ДополнительныеФайлы;
	
	Если ОтветHTTP <> Неопределено Тогда
		СтрокаОтвета = ПолучитьИдентификаторОтвета(ОтветHTTP, СтруктураОтвета);
	Иначе
		СтрокаОтвета = "";
	КонецЕсли;
	
	СтруктураЗначения = Новый Структура;
	
	Если ОтветHTTP <> Неопределено И Строка(ОтветHTTP.КодСостояния) = СтрокаОтвета Тогда 
		ОшибкаПоКлассификатору = Новый Структура("Причина, Решение, СпособУстранения, Ссылка");
		ОшибкаПоКлассификатору.Причина = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ОписаниеОшибкиHTTP(ОтветHTTP.КодСостояния), ОтветHTTP.КодСостояния);
		СтруктураЗначения.Вставить("СтрокаПоискаОшибки", ОтветHTTP.КодСостояния);
		СтруктураЗначения.Вставить("ОшибкаПоКлассификаторуНайдена", Ложь);
		
		МетодикиУстранения = Новый Массив;
		МетодикиУстранения.Добавить("ПовторнаяОтправка");
		МетодикиУстранения.Добавить("НеЗапрашиватьСтатусДоверенности");
		
		СпособУстранения = Новый Структура("МетодикиУстранения", МетодикиУстранения);
		ОшибкаПоКлассификатору.СпособУстранения = ОбщегоНазначения.ЗначениеВJSON(СпособУстранения);
	Иначе
		Если ЗапросHTTP <> Неопределено Тогда
			СтрокаЗапроса = ПолучитьИдентификаторЗапроса(ЗапросHTTP);
		Иначе
			СтрокаЗапроса = "";
		КонецЕсли;
		
		Если СтрокаЗапроса + СтрокаОтвета = "" Тогда
			СтрокаПоискаОшибки = ТекстОшибки;
		Иначе
			СтрокаПоискаОшибки = СтрокаЗапроса + "|" + СтрокаОтвета;
		КонецЕсли;
		ОшибкаПоКлассификатору = ЭлектроннаяПодпись.ОшибкаПоКлассификатору(СтрокаПоискаОшибки, Истина);
		
		СтруктураЗначения.Вставить("СтрокаПоискаОшибки", СтрокаПоискаОшибки);
		СтруктураЗначения.Вставить("ОшибкаПоКлассификаторуНайдена", ОшибкаПоКлассификатору <> Неопределено);
	КонецЕсли;
			
	Если ОшибкаПоКлассификатору = Неопределено Тогда
		ОшибкаПоКлассификатору = Новый Структура("Причина, Решение, СпособУстранения, Ссылка");
	КонецЕсли;
	
	ОшибкаПоКлассификатору.Причина = СтроковыеФункцииКлиентСервер.ВставитьПараметрыВСтроку(ОшибкаПоКлассификатору.Причина, ПараметрыТекстаОшибки);
	
	ОшибкаПоКлассификатору.Вставить("ТекстОшибки", 
		ОбщегоНазначенияКлиентСервер.СвойствоСтруктуры(СтруктураОтвета, "title", ТекстОшибки));
	ОшибкаПоКлассификатору.Вставить("ЗаголовокОшибки", ЗаголовокОшибки);
	СтруктураЗначения.Вставить("ОшибкаПоКлассификатору", ОшибкаПоКлассификатору); 
	
	ДанныеФайла = ПолучитьДвоичныеДанныеИзСтроки(ОбщегоНазначения.ЗначениеВСтрокуXML(СтруктураЗначения));
	Если ДополнительныеФайлы = Неопределено Тогда
		ДополнительныеФайлы = Новый Массив;
	КонецЕсли;
	ДобавитьФайлДляРасследования(ДополнительныеФайлы, ДанныеФайла, НСтр("ru='Ошибка по классификатору'"), "xml");
	ОшибкаПоКлассификатору.Вставить("ДополнительныеФайлы", ДополнительныеФайлы);
		
	Возврат ОшибкаПоКлассификатору;

КонецФункции

Функция ОписаниеОшибкиHTTP(КодСостояния)
	
	Если КодСостояния < 300 Тогда
		Возврат "";
	ИначеЕсли КодСостояния = 300 Тогда
		Возврат НСтр("ru = 'Множественный выбор при отправке ответа сервера'");
	ИначеЕсли КодСостояния = 301 Тогда
		Возврат НСтр("ru = 'Ресурс перемещен'");
	ИначеЕсли КодСостояния = 302 Тогда
		Возврат НСтр("ru = 'Ресурс временно перемещен'");
	ИначеЕсли КодСостояния = 303 Тогда
		Возврат НСтр("ru = 'Ресурс перемещен на другой адрес'");
	ИначеЕсли КодСостояния = 304 Тогда
		Возврат НСтр("ru = 'Неожиданный ответ об отсутствии изменений страницы'");
	ИначеЕсли КодСостояния = 305 Тогда
		Возврат НСтр("ru = 'Для доступа к ресурсу требуется прокси'");
	ИначеЕсли КодСостояния = 306 Тогда
		Возврат НСтр("ru = 'Неиспользуемый код перенаправления запроса'");
	ИначеЕсли КодСостояния = 307 Тогда
		Возврат НСтр("ru = 'Временное перенаправление'");
	ИначеЕсли КодСостояния < 400 Тогда
		Возврат СтрШаблон(
			НСтр("ru = 'Ошибка по перенаправлению запроса с кодом %1'"),
			Формат(КодСостояния, "ЧДЦ=; ЧН=; ЧГ="));
	ИначеЕсли КодСостояния = 400 Тогда
		Возврат НСтр("ru = 'Неверный формат запроса'");
	ИначеЕсли КодСостояния = 401 Тогда
		Возврат НСтр("ru = 'Требуется аутентификация'");
	ИначеЕсли КодСостояния = 402 Тогда
		Возврат НСтр("ru = 'Требуется оплата'");
	ИначеЕсли КодСостояния = 403 Тогда
		Возврат НСтр("ru = 'Доступ к ресурсу запрещен'");
	ИначеЕсли КодСостояния = 404 Тогда
		Возврат НСтр("ru = 'Запрошенная страница не найдена'");
	ИначеЕсли КодСостояния = 405 Тогда
		Возврат НСтр("ru = 'Используемый метод запрещен'");
	ИначеЕсли КодСостояния = 406 Тогда
		Возврат НСтр("ru = 'Отсутствуют подходящие ответы'");
	ИначеЕсли КодСостояния = 407 Тогда
		Возврат НСтр("ru = 'Требуется аутентификация прокси'");
	ИначеЕсли КодСостояния = 408 Тогда
		Возврат НСтр("ru = 'Лимит времени сервера при ожидании запроса исчерпан'");
	ИначеЕсли КодСостояния = 409 Тогда
		Возврат НСтр("ru = 'Конфликт с текущим состоянием ресурса, требуется больше информации'");
	ИначеЕсли КодСостояния = 410 Тогда
		Возврат НСтр("ru = 'Ресурс более недоступен'");
	ИначеЕсли КодСостояния = 411 Тогда
		Возврат НСтр("ru = 'Требуется задание длины содержимого'");
	ИначеЕсли КодСостояния = 412 Тогда
		Возврат НСтр("ru = 'Ошибочные условия заголовочных полей'");
	ИначеЕсли КодСостояния = 413 Тогда
		Возврат НСтр("ru = 'Слишком большая длина запроса'");
	ИначеЕсли КодСостояния = 414 Тогда
		Возврат НСтр("ru = 'Запрошенный идентификатор слишком велик'");
	ИначеЕсли КодСостояния = 415 Тогда
		Возврат НСтр("ru = 'Неподдерживаемый тип данных запроса'");
	ИначеЕсли КодСостояния = 416 Тогда
		Возврат НСтр("ru = 'Запрошенный промежуток невыполним'");
	ИначеЕсли КодСостояния = 417 Тогда
		Возврат НСтр("ru = 'Несоответствие ожиданиям'");
	ИначеЕсли КодСостояния = 422 Тогда
		Возврат НСтр("ru = 'Необрабатываемый объект'");
	ИначеЕсли КодСостояния = 423 Тогда
		Возврат НСтр("ru = 'Заблокировано'");
	ИначеЕсли КодСостояния = 424 Тогда
		Возврат НСтр("ru = 'Сбой взаимосвязанного вызова'");
	ИначеЕсли КодСостояния = 449 Тогда
		Возврат НСтр("ru = 'Возврат запроса после необходимого действия'");
	ИначеЕсли КодСостояния < 500 Тогда
		Возврат СтрШаблон(
			НСтр("ru = 'Ошибка клиента с кодом %1'"),
			Формат(КодСостояния, "ЧДЦ=; ЧН=; ЧГ="));
	ИначеЕсли КодСостояния = 500 Тогда
		Возврат НСтр("ru = 'Внутренняя ошибка сервера'");
	ИначеЕсли КодСостояния = 501 Тогда
		Возврат НСтр("ru = 'Процесс для данного запроса не поддерживается сервером'");
	ИначеЕсли КодСостояния = 502 Тогда
		Возврат НСтр("ru = 'Gateway-сервер получил ошибочный ответ'");
	ИначеЕсли КодСостояния = 503 Тогда
		Возврат НСтр("ru = 'Сервер распределенного реестра временно недоступен'");
	ИначеЕсли КодСостояния = 504 Тогда
		Возврат НСтр("ru = 'Превышено время ожидание ответа на запрос Gateway-сервера'");
	ИначеЕсли КодСостояния = 505 Тогда
		Возврат НСтр("ru = 'Версия HTTP не поддерживается сервером'");
	ИначеЕсли КодСостояния = 506 Тогда
		Возврат НСтр("ru = 'Вариантный тип содержит также вариант'");
	ИначеЕсли КодСостояния = 507 Тогда
		Возврат НСтр("ru = 'Переполнение хранилища'");
	ИначеЕсли КодСостояния = 510 Тогда
		Возврат НСтр("ru = 'Отсутствует поддержка расширений'");
	ИначеЕсли КодСостояния < 600 Тогда
		Возврат СтрШаблон(
			НСтр("ru = 'Ошибка сервера с кодом %1'"),
			Формат(КодСостояния, "ЧДЦ=; ЧН=; ЧГ="));
	ИначеЕсли КодСостояния = 999 Тогда
		Возврат НСтр("ru = 'Разрушительный сбой сервера'");
	Иначе
		Возврат СтрШаблон(
			НСтр("ru = 'Ошибка с кодом %1'"),
			Формат(КодСостояния, "ЧДЦ=; ЧН=; ЧГ="));
	КонецЕсли;

КонецФункции

	// Устанавливает соединение с сервером Интернета по протоколу http(s).
//
// Параметры:
//  URL                 - Строка - url сервера в формате [Протокол://]<Сервер>/.
//  ПараметрыСоединения - Структура - дополнительные параметры для "тонкой" настройки:
//    * Таймаут - Число - определяет время ожидания осуществляемого соединения и операций, в секундах.
//
Функция СоединениеССерверомИнтернета(URL, ПараметрыСоединения = Неопределено) Экспорт

	СтруктураURI = ОбщегоНазначенияКлиентСервер.СтруктураURI(URL);
	Схема = ?(ЗначениеЗаполнено(СтруктураURI.Схема), СтруктураURI.Схема, "http");
	Прокси = ПолучениеФайловИзИнтернета.ПолучитьПрокси(Схема);
	
	Таймаут = 30;
	Если ТипЗнч(ПараметрыСоединения) = Тип("Структура") Тогда
		Если ПараметрыСоединения.Свойство("Таймаут") Тогда
			Таймаут = ПараметрыСоединения.Таймаут;
		КонецЕсли;
	КонецЕсли;
	
	Попытка
		Соединение = Новый HTTPСоединение(
			СтруктураURI.Хост,
			СтруктураURI.Порт,
			СтруктураURI.Логин,
			СтруктураURI.Пароль, 
			Прокси,
			Таймаут,
			?(НРег(Схема) = "http", Неопределено, ОбщегоНазначенияКлиентСервер.НовоеЗащищенноеСоединение()));
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();	
		ЗаписьЖурналаРегистрации(ИмяСобытияЖурналаРегистрации() +"."
			+ НСтр("ru = 'Установление соединения с сервером интернета'", ОбщегоНазначения.КодОсновногоЯзыка()),
			УровеньЖурналаРегистрации.Ошибка,,,
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
		ВызватьИсключение;
	КонецПопытки;
	
	Возврат Соединение;
	
КонецФункции

Процедура СброситьДанныеАутентификацииНаПорталеПоддержки()
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если ОбщегоНазначения.ПодсистемаСуществует("ИнтернетПоддержкаПользователей") Тогда
		МодульИнтернетПоддержкаПользователей = ОбщегоНазначения.ОбщийМодуль("ИнтернетПоддержкаПользователей");
		Если МодульИнтернетПоддержкаПользователей.ДоступноПодключениеИнтернетПоддержки() Тогда
			МодульИнтернетПоддержкаПользователей.СохранитьДанныеАутентификации(Неопределено);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

Процедура ДобавитьФайлДляРасследования(Файлы, ДанныеФайла, ТипФайла, Расширение = "txt")
	СведенияОФайле = Новый Структура;
	Если ТипЗнч(ДанныеФайла) = Тип("Строка") Тогда
		СведенияОФайле.Вставить("Данные", Новый ДвоичныеДанные(ДанныеФайла));
	ИначеЕсли ТипЗнч(ДанныеФайла) = Тип("ДвоичныеДанные") Тогда
		СведенияОФайле.Вставить("Данные", ДанныеФайла);
	Иначе
		СведенияОФайле.Вставить("Данные", Неопределено);
	КонецЕсли;
	СведенияОФайле.Вставить("Имя", ТипФайла + "." + Расширение);
	СведенияОФайле.Вставить("ТипФайла", ТипФайла);
	Файлы.Добавить(СведенияОФайле);	
КонецПроцедуры          

Функция ПолучитьИдентификаторЗапроса(ЗапросHTTP)
	Результат = "";
	Словарь = СтрРазделить("poar-webapp/integration/poa/generate-number/transactions/status/poaopen/public/poazip/zip/number/token", "/", Ложь);
	Синонимы = Новый Соответствие;
	Синонимы.Вставить("/vst-oauth2/oauth/token", "/token");
	Синонимы.Вставить("/poar-webapp/integration/poa/generate-number", "/number");
	Синонимы.Вставить("/poar-webapp/integration/poa", "/poa");
	Синонимы.Вставить("/poar-webapp/integration/poa/status", "/transactions");
	Синонимы.Вставить("/poar-webapp/integration/poa/public", "/poaopen");
	Синонимы.Вставить("/poar-webapp/integration/poa/zip", "/poazip");
	СловаЗапроса = СтрРазделить(ЗапросHTTP.АдресРесурса, "/?", Ложь);
	Для Каждого Слово Из СловаЗапроса Цикл
		Если Словарь.Найти(Слово) <> Неопределено Тогда
			Результат = Результат + "/" + Слово;
		КонецЕсли;
	КонецЦикла;
	Синоним = Синонимы[Результат];
	Возврат ?(Синоним = Неопределено, Результат, Синоним);
КонецФункции  

Функция ПолучитьИдентификаторОтвета(ОтветHTTP, СтруктураОтвета)
	Если СтруктураОтвета = Неопределено Или ОтветHTTP.КодСостояния = 500  Тогда
		Возврат Строка(ОтветHTTP.КодСостояния);
	ИначеЕсли СтруктураОтвета.Свойство("error") Тогда
		КодОшибки = СтруктураОтвета.error;
	ИначеЕсли СтруктураОтвета.Свойство("type") Тогда
		КодОшибки = СтруктураОтвета.type;
	КонецЕсли;  
	
	Если Не ЗначениеЗаполнено(КодОшибки) Тогда
		Возврат Строка(ОтветHTTP.КодСостояния);
	КонецЕсли;
	
	Возврат КодОшибки;
КонецФункции

Функция ПараметрыФайловДляРасследования()
	
	ПараметрыФайловДляРасследования = Новый Структура;
	ПараметрыФайловДляРасследования.Вставить("ИмяФайлаЗапроса", "");
	ПараметрыФайловДляРасследования.Вставить("ИмяФайлаОтвета", "");
	ПараметрыФайловДляРасследования.Вставить("Запрос", Неопределено);
	ПараметрыФайловДляРасследования.Вставить("Ответ", Неопределено);
	ПараметрыФайловДляРасследования.Вставить("СоединениеHTTP", Неопределено);
	Возврат ПараметрыФайловДляРасследования;

КонецФункции

Функция ФайлыДляРасследования(ПараметрыФайловДляРасследования)
	
	Запрос = ПараметрыФайловДляРасследования.Запрос;
	Ответ = ПараметрыФайловДляРасследования.Ответ;
	СоединениеHTTP = ПараметрыФайловДляРасследования.СоединениеHTTP;
	
	ДополнительныеФайлы = Новый Массив;
	
	Если Запрос <> Неопределено Тогда
		АдресРесурса = Запрос.АдресРесурса;
		Заголовки = Запрос.Заголовки;
		УбратьИнформациюОДоступе(АдресРесурса, Заголовки);
		RestЗапрос = RestПредставлениеЗапроса(Запрос, СоединениеHTTP);
		ДанныеФайла = ПолучитьДвоичныеДанныеИзСтроки(RestЗапрос);
		ДобавитьФайлДляРасследования(ДополнительныеФайлы, ДанныеФайла, НСтр("ru='Запрос http'"), "rest");
	КонецЕсли;
	
	Если Ответ <> Неопределено Тогда
		СтруктураЗначения = Новый Структура;
		СтруктураЗначения.Вставить("КодСостояния", Ответ.КодСостояния);
		Заголовки = Ответ.Заголовки;
		УбратьИнформациюОДоступе(АдресРесурса, Заголовки);
		СтруктураЗначения.Вставить("Заголовки", Заголовки);
		СтруктураЗначения.Вставить("Тело", Ответ.ПолучитьТелоКакСтроку());
		ДанныеФайла = ПолучитьДвоичныеДанныеИзСтроки(ОбщегоНазначения.ЗначениеВJSON(СтруктураЗначения));
		ДобавитьФайлДляРасследования(ДополнительныеФайлы, ДанныеФайла, НСтр("ru='Ответ http'"), "json");
	КонецЕсли;
	
	Возврат ДополнительныеФайлы;
КонецФункции     

Функция RestПредставлениеЗапроса(Запрос, СоединениеHTTP)
	RestЗапрос = Новый Массив;
	RestЗапрос.Добавить("###");
	RestЗапрос.Добавить(Символы.ПС);
	АдресРесурса = ?(СоединениеHTTP.ЗащищенноеСоединение = Неопределено, "http://", "https://") + СоединениеHTTP.Сервер + "/" + Запрос.АдресРесурса;
	СтрокаЗапроса = ?(ЗначениеЗаполнено(Запрос.ПолучитьТелоКакСтроку()), "POST", "GET") + " " + АдресРесурса + " HTTP/1.1";
	RestЗапрос.Добавить(СтрокаЗапроса);
	Для Каждого Заголовок Из Запрос.Заголовки Цикл
		RestЗапрос.Добавить(Заголовок.Ключ+": "+Заголовок.Значение);
	КонецЦикла;
	
	RestЗапрос.Добавить(Символы.ПС);
	RestЗапрос.Добавить(Запрос.ПолучитьТелоКакСтроку()); 
	RestЗапрос.Добавить(Символы.ПС);
	RestЗапрос.Добавить("###");
	Возврат СтрСоединить(RestЗапрос, Символы.ПС);
КонецФункции

Процедура УбратьИнформациюОДоступе(Строка, Заголовки)
	Если Заголовки.Получить("username") <> Неопределено Тогда
		Заголовки.Вставить("username", "*");
	КонецЕсли;
	
	Если Заголовки.Получить("password") <> Неопределено Тогда
		Заголовки.Вставить("password", "*");
	КонецЕсли;
	
	Позиция = СтрНайти(Строка, "?login=");
	Если Позиция > 0 Тогда
		Строка = Лев(Строка, Позиция -1)+"?login=*&password=*";
	КонецЕсли;
	
КонецПроцедуры

Функция ДатаИзСтрокиРазныхФорматов(СтрокаДаты)
	
	Если ТипЗнч(СтрокаДаты) = Тип("Дата") Тогда
		Возврат СтрокаДаты;
	КонецЕсли;
	
	Возврат ПрочитатьДатуJSON(СтрокаДаты, ФорматДатыJSON.ISO);
	
КонецФункции

Функция СтатусТранзакцииПеречислением(СтатусТранзакцииСтрокой)
	Если СтатусТранзакцииСтрокой = "SUCCESS" Тогда
		Возврат Перечисления.СтатусыТранзакцииСРеестромМЧД.Успешно;
	ИначеЕсли СтатусТранзакцииСтрокой = "FAILURE" Тогда
		Возврат Перечисления.СтатусыТранзакцииСРеестромМЧД.Ошибка;
	ИначеЕсли СтатусТранзакцииСтрокой = "PENDING" Тогда
		Возврат Перечисления.СтатусыТранзакцииСРеестромМЧД.ОжидаетОбработки;
	КонецЕсли;
	Возврат Перечисления.СтатусыТранзакцииСРеестромМЧД.ПустаяСсылка();
КонецФункции

#КонецОбласти  

#Область ТехническийСтатусДокумента

Функция ПрочитатьСостояниеМЧД(Доверенность) Экспорт
	Доверенности = ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Доверенность);
	СостояниеМассиваМЧД = ПрочитатьСостояниеМассиваМЧД(Доверенности);
	Если СостояниеМассиваМЧД.Количество() > 0 Тогда
		Возврат СостояниеМассиваМЧД[Доверенность];
	Иначе
		Возврат СостояниеДоверенности();
	КонецЕсли;
КонецФункции

Функция СостояниеДоверенности()
	Результат = Новый Структура;
	Результат.Вставить("Доверенность");
	Результат.Вставить("ОписаниеСостояния", "");
	Результат.Вставить("ДатаТранзакции");
	Результат.Вставить("ТипТранзакции");
	Результат.Вставить("ТехническийСтатус");
	Результат.Вставить("СтатусТранзакции");
	Результат.Вставить("Статус");
	Результат.Вставить("Подписана");
	Результат.Вставить("ДатаЗапросаСтатуса");
	Результат.Вставить("ДанныеОшибкиЗапросаСтатуса");
	Результат.Вставить("ОтображатьСтатусВДокументе", Ложь);
	Возврат Результат;
КонецФункции

Функция ПрочитатьСостояниеМассиваМЧД(Доверенности)
	
	СостояниеДоверенностей = Новый Соответствие;
	
	Запрос = Новый Запрос;
	Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ
	               |	МашиночитаемыеДоверенностиСтатусы.МашиночитаемаяДоверенность КАК Доверенность,
	               |	МашиночитаемыеДоверенностиСтатусы.ИдентификаторТранзакции КАК ИдентификаторТранзакции,
	               |	МашиночитаемыеДоверенностиСтатусы.ТехническийСтатус КАК ТехническийСтатус,
	               |	МашиночитаемыеДоверенностиСтатусы.СтатусТранзакции КАК СтатусТранзакции,
	               |	МашиночитаемыеДоверенностиСтатусы.Подписана КАК Подписана,
	               |	МашиночитаемыеДоверенностиСтатусы.ТипТранзакции КАК ТипТранзакции,
	               |	МашиночитаемыеДоверенностиСтатусы.ДатаТранзакции КАК ДатаТранзакции,
	               |	МашиночитаемыеДоверенностиСтатусы.ДатаЗапросаСтатуса КАК ДатаЗапросаСтатуса,
	               |	МашиночитаемыеДоверенностиСтатусы.ДанныеОшибкиЗапросаСтатуса КАК ДанныеОшибкиЗапросаСтатуса,
	               |	МашиночитаемыеДоверенности.Статус КАК Статус,
	               |	ВЫБОР
	               |		КОГДА МашиночитаемыеДоверенностиСтатусы.ТехническийСтатус В (&СтатусыБезПодробностей)
	               |			ТОГДА ЛОЖЬ
	               |		ИНАЧЕ ИСТИНА
	               |	КОНЕЦ КАК ОтображатьСтатусВДокументе
	               |ИЗ
	               |	РегистрСведений.МашиночитаемыеДоверенностиСтатусы КАК МашиночитаемыеДоверенностиСтатусы
	               |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.МашиночитаемыеДоверенности КАК МашиночитаемыеДоверенности
	               |		ПО МашиночитаемыеДоверенностиСтатусы.МашиночитаемаяДоверенность = МашиночитаемыеДоверенности.Ссылка
	               |ГДЕ
	               |	МашиночитаемыеДоверенностиСтатусы.МашиночитаемаяДоверенность В(&Доверенности)";
	Запрос.УстановитьПараметр("Доверенности", Доверенности);
	СтатусыБезПодробностей = Новый Массив;
	СтатусыБезПодробностей.Добавить(Перечисления.ТехническиеСтатусыМЧД.Создание);
	СтатусыБезПодробностей.Добавить(Перечисления.ТехническиеСтатусыМЧД.Подписание);
	СтатусыБезПодробностей.Добавить(Перечисления.ТехническиеСтатусыМЧД.Подписана);
	СтатусыБезПодробностей.Добавить(Перечисления.ТехническиеСтатусыМЧД.Просрочена);
	СтатусыБезПодробностей.Добавить(Перечисления.ТехническиеСтатусыМЧД.Отменена);
	
	Запрос.УстановитьПараметр("СтатусыБезПодробностей", СтатусыБезПодробностей);
	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();
	Пока Выборка.Следующий() Цикл
		СостояниеДоверенности = СостояниеДоверенности();
		ЗаполнитьЗначенияСвойств(СостояниеДоверенности, Выборка);
		
		Если Выборка.ДатаТранзакции <> Дата(1,1,1) Тогда
			ОписаниеСостояния = СтроковыеФункции.ФорматированнаяСтрока(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">Запрос в реестр ФНС отправлен %2</span>'"), "ПоясняющийТекст", ОтформатироватьДату(Выборка.ДатаТранзакции)));
		ИначеЕсли ЗначениеЗаполнено(Выборка.ТехническийСтатус) Тогда
			ОписаниеСостояния = СтроковыеФункции.ФорматированнаяСтрока(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">%2</span>'"), "ПоясняющийТекст", Выборка.ТехническийСтатус));
		Иначе
			ОписаниеСостояния = СтроковыеФункции.ФорматированнаяСтрока(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">Запрос в реестр ФНС не направлялся</span>'"), "ПоясняющийТекст"));
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Выборка.ДатаЗапросаСтатуса) И Выборка.ТехническийСтатус <> Перечисления.ТехническиеСтатусыМЧД.Активна Тогда
			ОписаниеСостояния = Новый ФорматированнаяСтрока(ОписаниеСостояния, Символы.ПС, 
				СтроковыеФункции.ФорматированнаяСтрока(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">Состояние на %2</span>'"), "ПоясняющийТекст", ОтформатироватьДату(Выборка.ДатаЗапросаСтатуса))));	
		КонецЕсли;
		
		Если Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.ОжидаетОбработки
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Регистрация Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: Ожидает регистрации</span>'"), "ПоясняющийТекст");
		ИначеЕсли Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.ОжидаетОбработки
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Отмена Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: Ожидает отмены</span>'"), "ПоясняющийТекст");
		ИначеЕсли Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.Успешно
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Регистрация
			И Выборка.ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Регистрация Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: Ожидает регистрации в ИР «Доверенность»</span>'"), "ПоясняющийТекст");
		ИначеЕсли Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.Успешно
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Регистрация Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: Успешно зарегистрирована</span>'"), "ПоясняющийТекст");
		ИначеЕсли Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.Успешно
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Отмена Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: Успешно отменена</span>'"), "ПоясняющийТекст");
		ИначеЕсли Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.Ошибка
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Регистрация Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: <a href = ""%2"">Ошибка регистрации</a>'"), "ПоясняющийТекст", "ПоказатьОшибку");
		ИначеЕсли Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.Ошибка
			И Выборка.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Отмена Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: <a href = ""%2"">Ошибка отмены</a>'"), "ПоясняющийТекст", "ПоказатьОшибку");
		ИначеЕсли ЗначениеЗаполнено(Выборка.ДатаТранзакции) И Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.Ошибка Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: <a href = ""%2"">Не удалось получить статус</a>'"), "ПоясняющийТекст", "ПоказатьОшибку");
		ИначеЕсли Выборка.ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Регистрация 
			И Выборка.СтатусТранзакции = Перечисления.СтатусыТранзакцииСРеестромМЧД.ПустаяСсылка() Тогда
			ОписаниеСобытия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru='<span style=""color: %1"">: <a href = ""%2"">Ошибка регистрации</a>'"), "ПоясняющийТекст", "ПоказатьОшибку");
		КонецЕсли;
		
		ОписаниеСостояния = Новый ФорматированнаяСтрока(ОписаниеСостояния, 
			СтроковыеФункции.ФорматированнаяСтрока(ОписаниеСобытия));
		СостояниеДоверенности.ОписаниеСостояния = ОписаниеСостояния;
		СостояниеДоверенности.ДанныеОшибкиЗапросаСтатуса = СостояниеДоверенности.ДанныеОшибкиЗапросаСтатуса.Получить();
		СостояниеДоверенностей.Вставить(Выборка.Доверенность, СостояниеДоверенности);
	КонецЦикла;
	Возврат СостояниеДоверенностей;
КонецФункции

Функция ОтформатироватьДату(Дата)
	Если НачалоДня(Дата) = НачалоДня(ТекущаяДатаСеанса()) Тогда
		ДатаТекстом = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'сегодня %1'"), Формат(Дата, НСтр("ru='ДФ=HH:mm'")));
	Иначе
		ДатаТекстом = Формат(Дата, НСтр("ru='ДФ=dd.MM.yyyy HH:mm'"));
	КонецЕсли;
	Возврат ДатаТекстом;
КонецФункции

Функция ОбновитьИПрочитатьСтатусДоверенностей(Доверенности) Экспорт
	
	РегистрыСведений.МашиночитаемыеДоверенностиСтатусы.ОбновлениеСтатусовМЧД(Доверенности);
	ДанныеСостояний = ПрочитатьСостояниеМассиваМЧД(Доверенности);
	Возврат ДанныеСостояний;
	
КонецФункции

Функция РассчитатьТехническийСтатус(Доверенность, Знач Подписана = Неопределено, ЗаписыватьСтатус = Истина) Экспорт
	
	Если ТипЗнч(Доверенность) = Тип("СправочникОбъект.МашиночитаемыеДоверенности") Тогда
		ДоверенностьСсылка = Доверенность.Ссылка;
		РегистрироватьВРеестре = Доверенность.РегистрироватьВРеестре;
	Иначе
		ДоверенностьСсылка = Доверенность;
		РегистрироватьВРеестре = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Доверенность, "РегистрироватьВРеестре");
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	ВнешниеСтатусы = МашиночитаемыеДоверенностиФНССлужебныйКлиентСервер.ВнешниеСтатусы();
	
	Запись = РегистрыСведений.МашиночитаемыеДоверенностиСтатусы.СоздатьМенеджерЗаписи();
	Запись.МашиночитаемаяДоверенность = ДоверенностьСсылка;
	Запись.Прочитать();
	
	ЭтоВнешнийСтатус = ВнешниеСтатусы[Запись.ТехническийСтатус] = Истина;
	
	Если ЭтоВнешнийСтатус Тогда
		Если ТипЗнч(Доверенность) = Тип("СправочникОбъект.МашиночитаемыеДоверенности") И Не РегистрироватьВРеестре Тогда
			Доверенность.РегистрироватьВРеестре = Истина;
		КонецЕсли;
		Если Запись.Подписана И Подписана <> Истина Или Подписана = Неопределено Тогда
			Возврат Запись.ТехническийСтатус;
		КонецЕсли;
	КонецЕсли;
	
	ЗаписатьСтатус = Ложь;
	Если Подписана <> Неопределено И Запись.Подписана <> Подписана Тогда
		Запись.Подписана = Подписана;
		ЗаписатьСтатус = Истина;
	КонецЕсли;

	Если Не ЭтоВнешнийСтатус Тогда
		Если Запись.Подписана Тогда
			Если РегистрироватьВРеестре Тогда
				ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Подписана;
			Иначе
				ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Активна;
			КонецЕсли;
		Иначе
			ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Создание;
		КонецЕсли;
		Если Запись.ТехническийСтатус <> ТехническийСтатус Тогда
			Запись.ТехническийСтатус = ТехническийСтатус;
			ЗаписатьСтатус = Истина;
		КонецЕсли;
	КонецЕсли;
	
	Если ЗаписатьСтатус И ЗаписыватьСтатус Тогда
		Запись.МашиночитаемаяДоверенность = ДоверенностьСсылка;
		Запись.Записать();
	КонецЕсли;
	
	Возврат ТехническийСтатус;
	
КонецФункции

Процедура ОбновлениеСтатусовМЧД() Экспорт
	ОбщегоНазначения.ПриНачалеВыполненияРегламентногоЗадания(Метаданные.РегламентныеЗадания.ОбновлениеСтатусовМЧД);
	РегистрыСведений.МашиночитаемыеДоверенностиСтатусы.ОбновлениеСтатусовМЧД();
КонецПроцедуры

Функция ПолучитьЗначениеСтатуса(СтатусСтрокой) Экспорт
	ТехническийСтатус = Неопределено;
	СтатусДоверенности = СокрЛП(ВРег(СтатусСтрокой));
	
	Если СтатусДоверенности = "ACTIVE" Тогда
		ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Зарегистрирована;
	ИначеЕсли СтатусДоверенности = "REJECTED" Тогда
		ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.ОшибкаРегистрации;
	ИначеЕсли СтатусДоверенности = "PROCESSING" Тогда
		ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Регистрация;
	ИначеЕсли СтатусДоверенности = "EXPIRED" Тогда
		ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Просрочена;
	ИначеЕсли СтатусДоверенности = "REVOKED" Тогда
		ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Отменена;
	ИначеЕсли СтатусДоверенности = "CREATED" Тогда
		ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.ДатаНачалаДействияНеНаступила;
	КонецЕсли;
	
	Возврат ТехническийСтатус;
КонецФункции


#КонецОбласти

#Область ИнтерфейсРаботаСРаспределеннымРеестром

Функция АвторизоватьсяНаСервереМЧДРР(ЦельАвторизации = "") Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	ПараметрыРезультатаАвторизации = ПараметрыСеанса.ПараметрыАвторизацииВРаспределенномРеестре;
	Если ПараметрыРезультатаАвторизации <> Неопределено И ПараметрыРезультатаАвторизации.ДатаСеанса <> Неопределено
		И ПараметрыРезультатаАвторизации.РезультатАвторизации <> Неопределено Тогда
		
		ДатаСеанса = ТекущаяДатаСеанса();
		Если ПараметрыРезультатаАвторизации.ДатаСеанса >= ДатаСеанса - 60 * 60
			И ПараметрыРезультатаАвторизации.ДатаСеанса <= ДатаСеанса Тогда
			
			Возврат Новый Структура(ПараметрыРезультатаАвторизации.РезультатАвторизации);
		КонецЕсли;
	КонецЕсли;
	
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("ТокенДоступа", 			"");
	Результат.Вставить("ТекстОтвета", 			"");
	Результат.Вставить("Ошибка");
	
	РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/token", "/vst-oauth2/oauth/token");
	ПараметрыРесурсаНаСервере = "";
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI Тогда
		ТикетАутентификацииИлиДанныеПользователя = ТикетАутентификацииИлиДанныеПользователяНаПорталеПоддержки();
		
		Если ТикетАутентификацииИлиДанныеПользователя = Неопределено Тогда
			ЗаголовокОшибки = ?(ЦельАвторизации = "", НСтр("ru='Не удается авторизоваться на сайте интернет поддержки'"), ЦельАвторизации);
			ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, НСтр("ru='Не удается получить тикет аутентификации или данные пользователя.'"));
			Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
			Возврат Результат;
		КонецЕсли;
		
		Если ТикетАутентификацииИлиДанныеПользователя.Свойство("Тикет") Тогда
			ПараметрыРесурсаНаСервере = "?ticket=" + КодироватьСтроку(ТикетАутентификацииИлиДанныеПользователя.Тикет,
				СпособКодированияСтроки.КодировкаURL);
		Иначе
			ПараметрыРесурсаНаСервере = "?login=" + КодироватьСтроку(ТикетАутентификацииИлиДанныеПользователя.Логин,
				СпособКодированияСтроки.КодировкаURL)
				+ "&password=" + КодироватьСтроку(ТикетАутентификацииИлиДанныеПользователя.Пароль,
				СпособКодированияСтроки.КодировкаURL)
		КонецЕсли;
	КонецЕсли;
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Content-Type", "application/json");
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере + ПараметрыРесурсаНаСервере, ЗаголовкиHTTP);
	Если НЕ СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI Тогда
		СтруктураЗапроса = Новый Структура;
		СтруктураЗапроса.Вставить("username", СвойстваСервераМЧДРР.ЛогинОператора);
		СтруктураЗапроса.Вставить("password", СвойстваСервераМЧДРР.ПарольОператора);
		СтруктураЗапроса.Вставить("grant_type", "password");
		
		ТелоЗапроса = ОбщегоНазначения.ЗначениеВJSON(СтруктураЗапроса);
		ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса);
	КонецЕсли;
	
	ОтветHTTP = Неопределено;
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(СвойстваСервераМЧДРР.АдресСервера);
		
		Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI Тогда
			ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
		Иначе
			ОтветHTTP = СоединениеHTTP.ВызватьHTTPМетод("POST", ЗапросHTTP);
		КонецЕсли;
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ЗаголовокОшибки = ?(ЦельАвторизации = "", НСтр("ru='Не удается авторизоваться на сервере Распределенного реестра ФНС России'"), ЦельАвторизации);
		
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Попытка
		СтруктураОтвета = ПолучитьСтруктуруОтвета(ОтветHTTP);
		Результат.ТекстОтвета = ОтветHTTP.ПолучитьТелоКакСтроку();
		Результат.ТокенДоступа = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("access_token"),
			СтруктураОтвета.access_token, "");
		
		КодСостоянияПриНеверномЛогинеИлиПароле = 403;
		Если ОтветHTTP.КодСостояния = КодСостоянияПриНеверномЛогинеИлиПароле И СтруктураОтвета.Свойство("message") Тогда
			СброситьДанныеАутентификацииНаПорталеПоддержки();
		КонецЕсли;
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ЗаголовокОшибки = ?(ЦельАвторизации = "", НСтр("ru='Отказ при получении токена доступа на сервере Распределенного реестра ФНС России'"), ЦельАвторизации);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Если НЕ ЗначениеЗаполнено(Результат.ТокенДоступа) Тогда
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ЗаголовокОшибки = ?(ЦельАвторизации = "", НСтр("ru='Распределенный реестр ФНС России не предоставил токен для авторизации'"), ЦельАвторизации);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, 
			НСтр("ru='Распределенный реестр ФНС России не предоставил токен для авторизации.'"));
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецЕсли;
	
	ПараметрыРезультатаАвторизации = ПараметрыРезультатаАвторизацииНаСервереМЧД();
	ПараметрыРезультатаАвторизации.ДатаСеанса 			= ТекущаяДатаСеанса();
	ПараметрыРезультатаАвторизации.РезультатАвторизации = Новый ФиксированнаяСтруктура(Результат);
	ПараметрыСеанса.ПараметрыАвторизацииВРаспределенномРеестре = Новый ФиксированнаяСтруктура(ПараметрыРезультатаАвторизации);
	
	Возврат Результат;
	
КонецФункции

Функция ПолучитьНомерМЧДРР(ТокенДоступа = "") Экспорт
	
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("НомерДоверенности", 	"");
	Результат.Вставить("ТекстОтвета", 			"");
	Результат.Вставить("Ошибка");
	
	ЗаголовокОшибки = НСтр("ru='Не удалось получить номер доверенности'");
	
	Если НЕ ЗначениеЗаполнено(ТокенДоступа) Тогда
		РезультатАвторизации = АвторизоватьсяНаСервереМЧДРР(ЗаголовокОшибки);
		Если РезультатАвторизации.Ошибка <> Неопределено Тогда
			Результат.Ошибка = РезультатАвторизации.Ошибка;
		КонецЕсли;
		
		Если Результат.Ошибка <> Неопределено Тогда
			Возврат Результат;
		КонецЕсли;
		
		ТокенДоступа = РезультатАвторизации.ТокенДоступа;
	КонецЕсли;
	
		
	РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/number", "/poar-webapp/integration/poa/generate-number");
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	
	ЗаголовкиHTTP.Вставить(?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI, "authorizationtoken", "authorization"),
		"Bearer " + ТокенДоступа);
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере, ЗаголовкиHTTP);
	
	ОтветHTTP = Неопределено;
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(
			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
		
		ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		
		Возврат Результат;
	КонецПопытки;
	
	Попытка
		Результат.ТекстОтвета = ОтветHTTP.ПолучитьТелоКакСтроку();
		СтруктураОтвета = ПолучитьСтруктуруОтвета(ОтветHTTP);
		
		Результат.НомерДоверенности = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("poaNumber"),
			СтруктураОтвета.poaNumber, "");
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Если НЕ ЗначениеЗаполнено(Результат.НомерДоверенности) Тогда
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, 
			НСтр("ru='Распределенный реестр ФНС России не выдал номер доверенности.'"));
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ЗарегистрироватьМЧДРР(
		ИмяФайлаВыгрузки,
		ДанныеИлиАдресВыгрузки,
		ДанныеИлиАдресПодписи,
		ТокенДоступа = "",
		НомерДоверенности = "") Экспорт
		
	ДанныеВыгрузки = ?(ТипЗнч(ДанныеИлиАдресВыгрузки) = Тип("Строка")
		И ЭтоАдресВременногоХранилища(ДанныеИлиАдресВыгрузки), ПолучитьИзВременногоХранилища(ДанныеИлиАдресВыгрузки),
		ДанныеИлиАдресВыгрузки);
	ДанныеПодписи = ?(ТипЗнч(ДанныеИлиАдресПодписи) = Тип("Строка")
		И ЭтоАдресВременногоХранилища(ДанныеИлиАдресПодписи), ПолучитьИзВременногоХранилища(ДанныеИлиАдресПодписи),
		ДанныеИлиАдресПодписи);
		
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 				СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("ИдентификаторТранзакции", 	"");
	Результат.Вставить("НомерДоверенности", 		"");
	Результат.Вставить("ХешДоверенности", 			"");
	Результат.Вставить("ИННДоверителя", 			"");
	Результат.Вставить("ТекстОтвета", 				"");
	Результат.Вставить("Ошибка");
	
	ЗаголовокОшибки = НСтр("ru='Не удалось зарегистрировать доверенность'");
	
	Если НЕ ЗначениеЗаполнено(ТокенДоступа) Тогда
		РезультатАвторизации = АвторизоватьсяНаСервереМЧДРР(ЗаголовокОшибки);
		Если РезультатАвторизации.Ошибка <> Неопределено Тогда
			Результат.Ошибка = РезультатАвторизации.Ошибка;
			Возврат Результат;
		КонецЕсли;

		ТокенДоступа = РезультатАвторизации.ТокенДоступа;
	КонецЕсли;
		
	РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/poa", "/poar-webapp/integration/poa");
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Content-Type", "multipart/form-data; boundary=My1cV8bNdr");
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	ЗаголовкиHTTP.Вставить(?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI, "authorizationtoken", "authorization"),
		"Bearer " + ТокенДоступа);
	
	// запись передаваемых файлов
	
	МассивДвоичныхДанных = Новый Массив();
	
	ШаблонФайла = "--My1cV8bNdr
		|Content-Disposition: form-data; name=""poa""; filename=""%1""
		|Content-Type: text/xml
		|
		|";
	
	ШаблонФайла = СтрЗаменить(ШаблонФайла,  Символы.ПС, Символы.ВК + Символы.ПС);
	СодержимоеФайла = СтрШаблон(ШаблонФайла, ИмяФайлаВыгрузки);
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(СодержимоеФайла, "windows-1251"));	
	МассивДвоичныхДанных.Добавить(ДанныеВыгрузки);
	
	ШаблонФайла = "
		|--My1cV8bNdr
		|Content-Disposition: form-data; name=""signature""; filename=""%1.sig""
		|Content-Type: text/xml
		|
		|";
		
	ШаблонФайла = СтрЗаменить(ШаблонФайла,  Символы.ПС, Символы.ВК + Символы.ПС);
	СодержимоеФайла = СтрШаблон(ШаблонФайла, ИмяФайлаВыгрузки);
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(СодержимоеФайла, "windows-1251"));
	
	Подпись64 = Base64Строка(ДанныеПодписи);
	Подпись64 = СтрЗаменить(Подпись64, Символы.ВК, "");
	Подпись64 = СтрЗаменить(Подпись64, Символы.ПС, "");
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(Подпись64, "windows-1251"));
	
	ШаблонФайла = "
		|--My1cV8bNdr--";
	СодержимоеФайла = СтрЗаменить(ШаблонФайла,  Символы.ПС, Символы.ВК + Символы.ПС);
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(СодержимоеФайла, "windows-1251"));
	
	ПередаваемыеДанные = СоединитьДвоичныеДанные(МассивДвоичныхДанных);
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере, ЗаголовкиHTTP);
	ЗапросHTTP.УстановитьТелоИзДвоичныхДанных(ПередаваемыеДанные);
		
	ОтветHTTP = Неопределено;
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(
			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
		
		ОтветHTTP = СоединениеHTTP.ВызватьHTTPМетод("POST", ЗапросHTTP);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Попытка
		СтруктураОтвета = ПолучитьСтруктуруОтвета(ОтветHTTP);
		Результат.ИдентификаторТранзакции = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("txId"),
			СтруктураОтвета.txId, "");
		Результат.НомерДоверенности = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("poaNumber"),
			СтруктураОтвета.poaNumber, "");
		Результат.ХешДоверенности = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("poaId"),
			СтруктураОтвета.poaId, "");
		Результат.ИННДоверителя = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("issuerInn"),
			СтруктураОтвета.issuerInn, "");
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		
		Возврат Результат;
	КонецПопытки;
	
	Если НЕ ЗначениеЗаполнено(Результат.ИдентификаторТранзакции) Тогда
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки,
			 НСтр("ru='Распределенный реестр ФНС России не предоставил идентификационные данные.'"));
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		
		Возврат Результат;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ПолучитьСтатусТранзакцииМЧДРР(ИдентификаторТранзакции, ТокенДоступа = "", НомерДоверенности = "", ЦельПолучения = "") Экспорт
	
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 				СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("СтатусТранзакции", 			Перечисления.СтатусыМЧД.ПустаяСсылка());
	Результат.Вставить("ИдентификаторТранзакции", 	"");
	Результат.Вставить("ДатаВремяТранзакции", 		Дата(1, 1, 1));
	Результат.Вставить("ТекстОтвета", 				"");
	Результат.Вставить("Ошибка");
	
	ЗаголовокОшибки = ?(ЦельПолучения = "", НСтр("ru='Не удалось обновить статус транзакции'"), ЦельПолучения);
	
	Если НЕ ЗначениеЗаполнено(ТокенДоступа) Тогда
		РезультатАвторизации = АвторизоватьсяНаСервереМЧДРР(ЗаголовокОшибки);
		Если РезультатАвторизации.Ошибка <> Неопределено Тогда
			Результат.Ошибка = РезультатАвторизации.Ошибка;
		КонецЕсли;
		
		Если Результат.Ошибка <> Неопределено Тогда
			Возврат Результат;
		КонецЕсли;

		ТокенДоступа = РезультатАвторизации.ТокенДоступа;
	КонецЕсли;
	
		РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/transactions?txId=" + ИдентификаторТранзакции,
		"/poar-webapp/integration/poa/" + ИдентификаторТранзакции + "/status");
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	ЗаголовкиHTTP.Вставить(?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI, "authorizationtoken", "authorization"),
		"Bearer " + ТокенДоступа);
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере, ЗаголовкиHTTP);
	
	ОтветHTTP = Неопределено;
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(
			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
		
		ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Попытка
		Результат.ТекстОтвета = ОтветHTTP.ПолучитьТелоКакСтроку();
		СтруктураОтвета = ПолучитьСтруктуруОтвета(ОтветHTTP);
		СтатусТранзакции = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("status"),
			СтруктураОтвета.status, "");
			
		Результат.СтатусТранзакции = СтатусТранзакцииПеречислением(СтатусТранзакции);
		Результат.ИдентификаторТранзакции = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("txId"),
			СтруктураОтвета.txId, "");
		Результат.ДатаВремяТранзакции = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("timestamp"),
			ДатаИзСтрокиРазныхФорматов(СтруктураОтвета.timestamp), Дата(1,1,1));
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Если НЕ ЗначениеЗаполнено(Результат.ИдентификаторТранзакции) Тогда
		Результат.СтатусТранзакции = Перечисления.СтатусыМЧД.ПустаяСсылка();
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, 
			НСтр("ru='Распределенный реестр ФНС России не вернул данные о статусе транзакции.'"));
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ЧастичныеДанныеДоверенностиМЧДРР(НомерДоверенности, ТокенДоступа = "", ЦельПолучения = "") Экспорт
	
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("СтатусДоверенности", 	"");
	Результат.Вставить("ХешДоверенности", 		"");
	Результат.Вставить("НомерДоверенности", 	"");
	Результат.Вставить("ДатаВыдачи", 			Неопределено);
	Результат.Вставить("ДатаОкончания", 		Неопределено);
	Результат.Вставить("ДатаРегистрации", 		Неопределено);
	Результат.Вставить("ДатаИзмененияСтатуса", 	Неопределено);
	Результат.Вставить("ПубличныйКлюч", 		"");
	Результат.Вставить("ТекстОтвета", 			"");
	Результат.Вставить("Ошибка");
	
	ЗаголовокОшибки = ?(ЦельПолучения = "", НСтр("ru='Не удалось получить частичные данные доверенности'"), ЦельПолучения);
	
	Если НЕ ЗначениеЗаполнено(ТокенДоступа) Тогда
		РезультатАвторизации = АвторизоватьсяНаСервереМЧДРР(ЗаголовокОшибки);
		Если РезультатАвторизации.Ошибка <> Неопределено Тогда
			Результат.Ошибка = РезультатАвторизации.Ошибка;
		КонецЕсли;
		
		Если Результат.Ошибка <> Неопределено Тогда
			Возврат Результат;
		КонецЕсли;

		ТокенДоступа = РезультатАвторизации.ТокенДоступа;
	КонецЕсли;
	
	РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/poaopen?poaNumber=" + НомерДоверенности, "/poar-webapp/integration/poa/" + НомерДоверенности + "/public");
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	ЗаголовкиHTTP.Вставить(?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI, "authorizationtoken", "authorization"),
		"Bearer " + ТокенДоступа);
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере, ЗаголовкиHTTP);
	
	ОтветHTTP = Неопределено;
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(
			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
		
		ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP; 
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Попытка
		СтруктураОтвета = ПолучитьСтруктуруОтвета(ОтветHTTP);
		
		Результат.СтатусДоверенности = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("status"),
			СтруктураОтвета.status, "");
		Результат.ХешДоверенности = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("id"),
			СтруктураОтвета.id, "");
		Результат.НомерДоверенности = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("poaNumber"),
			СтруктураОтвета.poaNumber, "");
		Результат.ДатаВыдачи = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("startDate"),
			ДатаИзСтрокиРазныхФорматов(СтруктураОтвета.startDate), Неопределено);
		Результат.ДатаОкончания = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("endDate"),
			ДатаИзСтрокиРазныхФорматов(СтруктураОтвета.endDate), Неопределено);
		Результат.ДатаРегистрации = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("createdDate"),
			ДатаИзСтрокиРазныхФорматов(СтруктураОтвета.createdDate), Неопределено);
		Результат.ДатаИзмененияСтатуса = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("statusDate"),
			ДатаИзСтрокиРазныхФорматов(СтруктураОтвета.statusDate), Неопределено);
		Результат.ПубличныйКлюч = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("issuerPublicKey"),
			СтруктураОтвета.issuerPublicKey, "");
		Если ИспользуетсяРежимТестирования() Тогда
			ПараметрыМЧДФНС = ХранилищеОбщихНастроек.Загрузить("ДокументооборотСКонтролирующимиОрганами_ПараметрыМЧДФНС");
			Если ПараметрыМЧДФНС <> Неопределено Тогда
				ПараметрыДоверенности = ПараметрыМЧДФНС[Результат.НомерДоверенности];
				Если ПараметрыДоверенности <> Неопределено И ПараметрыДоверенности.Свойство("ВозвращаемыйСтатус") Тогда
					Результат.СтатусДоверенности = ПараметрыДоверенности.ВозвращаемыйСтатус;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP; 
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Если НЕ ЗначениеЗаполнено(Результат.ХешДоверенности) И НЕ ЗначениеЗаполнено(Результат.НомерДоверенности) Тогда
		Результат.СтатусДоверенности = "";
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, 
			НСтр("ru='Распределенный реестр ФНС России не предоставил частичных данных доверенности.'"));
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ПолныеДанныеДоверенностиМЧДРР(НомерДоверенности, ИННДоверителя, ТокенДоступа = "", ЦельПолучения = "")
	
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 					СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("ДанныеВыгрузки", 				Неопределено);
	Результат.Вставить("ДанныеПодписи", 				Неопределено);
	Результат.Вставить("ДанныеЗаявленияНаОтзыв", 		Неопределено);
	Результат.Вставить("ДанныеПодписиЗаявленияНаОтзыв", Неопределено);
	Результат.Вставить("ДанныеАрхива", 					Неопределено);
	Результат.Вставить("СтатусПолучения", 				"");
	Результат.Вставить("ТекстОтвета", 					"");
	Результат.Вставить("Ошибка");
	
	ЗаголовокОшибки = ?(ЦельПолучения = "", НСтр("ru='Не удалось получить полные данные доверенности'"), ЦельПолучения);
	
	Если НЕ ЗначениеЗаполнено(ТокенДоступа) Тогда
		РезультатАвторизации = АвторизоватьсяНаСервереМЧДРР(ЗаголовокОшибки);
		Если РезультатАвторизации.Ошибка <> Неопределено Тогда
			Результат.Ошибка = РезультатАвторизации.Ошибка;
		КонецЕсли;

		Если Результат.Ошибка <> Неопределено Тогда
			Возврат Результат;
		КонецЕсли;

		ТокенДоступа = РезультатАвторизации.ТокенДоступа;
	КонецЕсли;
	
	РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/poazip?poaNumber=" + НомерДоверенности + ?(ИННДоверителя = Неопределено, "", "&issuerInn=" + ИННДоверителя),
		"/poar-webapp/integration/poa/" + НомерДоверенности
			+ ?(ИННДоверителя = Неопределено, "", "/" + ИННДоверителя) + "/zip");
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	ЗаголовкиHTTP.Вставить(?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI, "authorizationtoken", "authorization"),
		"Bearer " + ТокенДоступа);
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере, ЗаголовкиHTTP);
	
	ОтветHTTP = Неопределено;
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
		
		ОтветHTTP = СоединениеHTTP.Получить(ЗапросHTTP);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Если НРег(ОтветHTTP.Заголовки["Content-Type"]) = "application/zip"
		ИЛИ НРег(ОтветHTTP.Заголовки["content-type"]) = "application/zip"
		ИЛИ НРег(ОтветHTTP.Заголовки["Content-Type"]) = "multipart"
		ИЛИ НРег(ОтветHTTP.Заголовки["content-type"]) = "multipart"
		ИЛИ НРег(Лев(ОтветHTTP.Заголовки["Content-Disposition"], 10)) = "attachment"
		ИЛИ НРег(Лев(ОтветHTTP.Заголовки["content-disposition"], 10)) = "attachment" Тогда
		
		Попытка
			Результат.ДанныеАрхива = ОтветHTTP.ПолучитьТелоКакДвоичныеДанные();
		Исключение
			ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
			ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
			ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
			ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
			ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
			ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
			ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
			ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
			ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
			ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
			ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
			Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
			Возврат Результат;
		КонецПопытки;
		
		Возврат Результат;
	КонецЕсли;
	
	Попытка
		Результат.ТекстОтвета = ОтветHTTP.ПолучитьТелоКакСтроку();
		СтруктураОтвета = ПолучитьСтруктуруОтвета(ОтветHTTP);
		
		Результат.СтатусПолучения = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("reqStatus"),
			СтруктураОтвета.reqStatus, "");
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;                        
	
	Если НЕ ЗначениеЗаполнено(Результат.СтатусПолучения) Тогда
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, 
			НСтр("ru='Распределенный реестр ФНС России не предоставил полных данных доверенности и не сообщил о статусе запроса данных.'"));
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		ПараметрыОшибкиМЧДРР.ПараметрыТекстаОшибки.Вставить("НомерДоверенности", НомерДоверенности);
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Функция ЗагрузитьДоверенностьИзРеестра(НомерДоверенности, ИННДоверителя, ТокенДоступа = "") Экспорт
	
	ЗаголовокОшибки = НСтр("ru='Не удалось загрузить доверенность'");
	
	РезультатПолучения = ПолныеДанныеДоверенностиМЧДРР(НомерДоверенности, ИННДоверителя, ТокенДоступа, ЗаголовокОшибки);
	ПолныеДанныеДоверенности = Новый Структура;
	ПолныеДанныеДоверенности.Вставить("Ошибка", РезультатПолучения.Ошибка);
	Если ЗначениеЗаполнено(РезультатПолучения.Ошибка) Тогда
		Возврат ПолныеДанныеДоверенности;
	КонецЕсли;
	
	Поток = РезультатПолучения.ДанныеАрхива.ОткрытьПотокДляЧтения();
	Архив = Новый ЧтениеZipФайла(Поток);
	ПутьВосстановления = ФайловаяСистема.СоздатьВременныйКаталог();
	
	Архив.ИзвлечьВсе(ПутьВосстановления, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
	ФайлыАрхива = НайтиФайлы(ПутьВосстановления, ПолучитьМаскуВсеФайлы());
	
	ФайлыДляЗагрузки = Новый Массив;
	Для Каждого ФайлАрхива Из ФайлыАрхива Цикл
		ОписаниеФайла = Новый Структура;
		ОписаниеФайла.Вставить("Имя", ФайлАрхива.ИмяБезРасширения);
		ОписаниеФайла.Вставить("ИмяФайла", ФайлАрхива.Имя);
		ОписаниеФайла.Вставить("ПолноеИмя", ФайлАрхива.ПолноеИмя);
		ОписаниеФайла.Вставить("Хранение", ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ФайлАрхива.ПолноеИмя), Новый УникальныйИдентификатор));
		ФайлыДляЗагрузки.Добавить(ОписаниеФайла);
	КонецЦикла;
		РезультатЗагрузки = Справочники.МашиночитаемыеДоверенности.ЗагрузитьДоверенностиВИнформационнуюБазу(ФайлыДляЗагрузки);
	
	Если ЗначениеЗаполнено(РезультатЗагрузки.ТекстОшибки) Тогда
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, РезультатЗагрузки.ТекстОшибки);
		ПолныеДанныеДоверенности.Вставить("Ошибка", ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР));
		Возврат ПолныеДанныеДоверенности;
	КонецЕсли;
	ФайловаяСистема.УдалитьВременныйКаталог(ПутьВосстановления);
	РегистрыСведений.МашиночитаемыеДоверенностиСтатусы.ОбновлениеСтатусовМЧД(РезультатЗагрузки.Доверенности);
	
	ПолныеДанныеДоверенности.Вставить("Доверенность", РезультатЗагрузки.Доверенности[0]);
	
	Возврат ПолныеДанныеДоверенности;
КонецФункции

Функция ОтменитьМЧДРР(ИмяФайлаВыгрузки, ДанныеИлиАдресВыгрузки, ДанныеИлиАдресПодписи, Доверенность, ТокенДоступа = "") Экспорт
	
	ЗаголовокОшибки = НСтр("ru='Не удалось отменить доверенность'");
	
	ДанныеВыгрузки = ?(ТипЗнч(ДанныеИлиАдресВыгрузки) = Тип("Строка")
		И ЭтоАдресВременногоХранилища(ДанныеИлиАдресВыгрузки), ПолучитьИзВременногоХранилища(ДанныеИлиАдресВыгрузки),
		ДанныеИлиАдресВыгрузки);
	ДанныеПодписи = ?(ТипЗнч(ДанныеИлиАдресПодписи) = Тип("Строка")
		И ЭтоАдресВременногоХранилища(ДанныеИлиАдресПодписи), ПолучитьИзВременногоХранилища(ДанныеИлиАдресПодписи),
		ДанныеИлиАдресПодписи);
	
	СвойстваСервераМЧДРР = СвойстваСервераМЧДРР();
	
	Результат = Новый Структура;
	Результат.Вставить("АдресСервера", 				СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
	Результат.Вставить("ИдентификаторТранзакции", 	"");
	Результат.Вставить("ТекстОтвета", 				"");
	Результат.Вставить("Ошибка", "");

	Если НЕ ЗначениеЗаполнено(ТокенДоступа) Тогда
		РезультатАвторизации = АвторизоватьсяНаСервереМЧДРР();
		ТокенДоступа = РезультатАвторизации.ТокенДоступа;
	КонецЕсли;
			
	РесурсНаСервере = СвойстваСервераМЧДРР.РесурсКорняAPI + ?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI,
		"/poacancel", "/poar-webapp/integration/poa/revoke");
	
	ЗаголовкиHTTP = Новый Соответствие();
	ЗаголовкиHTTP.Вставить("Content-Type", "multipart/form-data; boundary=My1cV8bNdr");
	ЗаголовкиHTTP.Вставить("Proxy-Connection", "Keep-Alive");
	ЗаголовкиHTTP.Вставить("Pragma", "no-cache");
	Если СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI И ИспользуетсяРежимТестирования() Тогда
		ЗаголовкиHTTP.Вставить("poaservertype", СвойстваСервераМЧДРР.ТестовыйСервер);
	КонецЕсли;
	ЗаголовкиHTTP.Вставить(?(СвойстваСервераМЧДРР.ИспользоватьРасширенияAPI, "authorizationtoken", "authorization"),
		"Bearer " + ТокенДоступа);
	
	// Запись передаваемых данных
	МассивДвоичныхДанных = Новый Массив();
	
	ШаблонФайла = "--My1cV8bNdr
		|Content-Disposition: form-data; name=""poaRevoke""; filename=""%1""
		|Content-Type: text/xml
		|
		|";
	
	ШаблонФайла = СтрЗаменить(ШаблонФайла,  Символы.ПС, Символы.ВК + Символы.ПС);
	СодержимоеФайла = СтрШаблон(ШаблонФайла, ИмяФайлаВыгрузки);
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(СодержимоеФайла, "windows-1251"));	
	МассивДвоичныхДанных.Добавить(ДанныеВыгрузки);
	
	ШаблонФайла = "
		|--My1cV8bNdr
		|Content-Disposition: form-data; name=""signature""; filename=""%1""
		|Content-Type: application/octet-stream
		|
		|";
	
	ШаблонФайла = СтрЗаменить(ШаблонФайла,  Символы.ПС, Символы.ВК + Символы.ПС);
	СодержимоеФайла = СтрШаблон(ШаблонФайла, ИмяФайлаВыгрузки);
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(СодержимоеФайла, "windows-1251"));
	
	Подпись64 = Base64Строка(ДанныеПодписи);
	Подпись64 = СтрЗаменить(Подпись64, Символы.ВК, "");
	Подпись64 = СтрЗаменить(Подпись64, Символы.ПС, "");
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(Подпись64, "windows-1251"));
	
	ШаблонФайла = "
		|--My1cV8bNdr--";
	СодержимоеФайла = СтрЗаменить(ШаблонФайла,  Символы.ПС, Символы.ВК + Символы.ПС);
	
	МассивДвоичныхДанных.Добавить(ПолучитьДвоичныеДанныеИзСтроки(СодержимоеФайла, "windows-1251"));
	
	ПередаваемыеДанные = СоединитьДвоичныеДанные(МассивДвоичныхДанных);
	
	ЗапросHTTP = Новый HTTPЗапрос(РесурсНаСервере, ЗаголовкиHTTP);
	ЗапросHTTP.УстановитьТелоИзДвоичныхДанных(ПередаваемыеДанные);
	
	Попытка
		СоединениеHTTP = СоединениеССерверомИнтернета(
			СвойстваСервераМЧДРР.АдресСервераБезАутентификации);
		
		ОтветHTTP = СоединениеHTTP.ВызватьHTTPМетод("POST", ЗапросHTTP);
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецПопытки;
	
	Попытка
		
		Результат.ТекстОтвета = ОтветHTTP.ПолучитьТелоКакСтроку();
		СтруктураОтвета	= ПолучитьСтруктуруОтвета(ОтветHTTP);
		
		Результат.ИдентификаторТранзакции = ?(ТипЗнч(СтруктураОтвета) = Тип("Структура") И СтруктураОтвета.Свойство("txId"),
			СтруктураОтвета.txId, "");
	Исключение
		ПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		
		Возврат Результат;
	КонецПопытки;
	
	Если НЕ ЗначениеЗаполнено(Результат.ИдентификаторТранзакции) Тогда
		ПредставлениеОшибки = НСтр("ru='Сервер МЧД не вернул номер транзакции отмены'");
		ПараметрыФайловДляРасследования = ПараметрыФайловДляРасследования();
		ПараметрыФайловДляРасследования.Запрос = ЗапросHTTP;
		ПараметрыФайловДляРасследования.Ответ = ОтветHTTP;
		ПараметрыФайловДляРасследования.СоединениеHTTP = СоединениеHTTP;
		ДополнительныеФайлы = ФайлыДляРасследования(ПараметрыФайловДляРасследования);
		ПараметрыОшибкиМЧДРР = ПараметрыОшибкиМЧДРР(ЗаголовокОшибки, ПредставлениеОшибки);
		ПараметрыОшибкиМЧДРР.ЗапросHTTP = ЗапросHTTP;
		ПараметрыОшибкиМЧДРР.ОтветHTTP = ОтветHTTP;
		ПараметрыОшибкиМЧДРР.СтруктураОтвета = СтруктураОтвета;
		ПараметрыОшибкиМЧДРР.ДополнительныеФайлы = ДополнительныеФайлы;
		Результат.Ошибка = ПолучитьИЗаписатьОшибкуМЧДРР(ПараметрыОшибкиМЧДРР);
		Возврат Результат;
	КонецЕсли;    
	
	УстановитьСтатусРегистрации(Доверенность, Результат.ИдентификаторТранзакции, Истина);
	
	Возврат Результат;
	
КонецФункции

Функция ПолучитьФайлОтменыДоверенности(Доверенность, ПричинаОтмены) Экспорт
	
	ФайлДоверенности = Доверенность.ФайлДоверенности;
	НомерДоверенности = Доверенность.НомерДоверенности;

	ДанныеФайла = РаботаСФайлами.ДанныеФайла(ФайлДоверенности);
	ДвоичныеДанные = ПолучитьИзВременногоХранилища(ДанныеФайла.СсылкаНаДвоичныеДанныеФайла);
	ДоверенностьXML = ПолучитьСтрокуИзДвоичныхДанных(ДвоичныеДанные);

	ДанныеДоверенности = Справочники.МашиночитаемыеДоверенности.ДоверенностьXDTO(ДоверенностьXML);
	Если ДанныеДоверенности = Неопределено Тогда
		ВызватьИсключение НСтр("ru = 'Не удалось распознать двоичные данные доверенности'");
	КонецЕсли;
	
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку("windows-1251");
	ЗаписьXML.ЗаписатьОбъявлениеXML();
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("Файл");
	ЗаписьXML.ЗаписатьАтрибут("ВерсФорм", "001");
	ЗаписьXML.ЗаписатьНачалоЭлемента("Документ");

	ЗаписьXML.ЗаписатьНачалоЭлемента("СвЗаяв");
	ЗаписьXML.ЗаписатьАтрибут("НомДовер", НомерДоверенности);
	ЗаписьXML.ЗаписатьАтрибут("ПричОтз", ПричинаОтмены);
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
	ЗаписьXML.ЗаписатьНачалоЭлемента("СвЗаявит");
	ЗаписьXML.ЗаписатьНачалоЭлемента("СвДоверит");
	
	Если Не ТипЗнч(ДанныеДоверенности) = Тип("Структура") Тогда
		Если ДанныеДоверенности.Документ.Довер.СвДоверит[0].ТипДоверит = "1" Тогда

			СведенияОДоверителе =
				ДанныеДоверенности.Документ.Довер.СвДоверит[0].Доверит.РосОргДовер.СвРосОрг;
				
			ЗаписьXML.ЗаписатьНачалоЭлемента("РосОргДовер");
			ЗаписьXML.ЗаписатьАтрибут("НаимОрг", СведенияОДоверителе.НаимОрг);
			ЗаписьXML.ЗаписатьАтрибут("ИННЮЛ", СведенияОДоверителе.ИННЮЛ);
			ЗаписьXML.ЗаписатьАтрибут("КПП", СведенияОДоверителе.КПП);
			ЗаписьXML.ЗаписатьАтрибут("ОГРН", СведенияОДоверителе.ОГРН);
			ЗаписьXML.ЗаписатьКонецЭлемента();

		ИначеЕсли ДанныеДоверенности.Документ.Довер.СвДоверит[0].ТипДоверит = "3" Тогда
			
			СведенияОДоверителе =
				ДанныеДоверенности.Документ.Довер.СвДоверит[0].Доверит.ИПДовер;
			
			ЗаписьXML.ЗаписатьНачалоЭлемента("ИПДовер");
			ЗаписьXML.ЗаписатьАтрибут("НаимИП", СведенияОДоверителе.НаимИП);
			ЗаписьXML.ЗаписатьАтрибут("ИННФЛ", СведенияОДоверителе.ИННФЛ);
			ЗаписьXML.ЗаписатьАтрибут("ОГРНИП", СведенияОДоверителе.ОГРНИП);
			ЗаписьXML.ЗаписатьКонецЭлемента();

		Иначе

			ТекстОшибки = НСтр("ru = 'Не поддерживается отзыв с типом доверителя:'") + ДанныеДоверенности.ТипОрганизации;
			ВызватьИсключение ТекстОшибки;

		КонецЕсли;
	Иначе
		Если ДанныеДоверенности.ТипОрганизации = "ЮЛ" Тогда

			ЗаписьXML.ЗаписатьНачалоЭлемента("РосОргДовер");
			ЗаписьXML.ЗаписатьАтрибут("НаимОрг", ДанныеДоверенности.ДоверительЮЛ_НаимОрг);
			ЗаписьXML.ЗаписатьАтрибут("ИННЮЛ", ДанныеДоверенности.ДоверительЮЛ_ИНН);
			ЗаписьXML.ЗаписатьАтрибут("КПП", ДанныеДоверенности.ДоверительЮЛ_КПП);
			ЗаписьXML.ЗаписатьАтрибут("ОГРН", ДанныеДоверенности.ДоверительЮЛ_ОГРН);
			ЗаписьXML.ЗаписатьКонецЭлемента();

		ИначеЕсли ДанныеДоверенности.ТипОрганизации = "ИП" Тогда

			ЗаписьXML.ЗаписатьНачалоЭлемента("ИПДовер");
			ЗаписьXML.ЗаписатьАтрибут("НаимИП", ДанныеДоверенности.ДоверительЮЛ_НаимОрг);
			ЗаписьXML.ЗаписатьАтрибут("ИННФЛ", ДанныеДоверенности.ДоверительФЛ_ИНН);
			ЗаписьXML.ЗаписатьАтрибут("ОГРНИП", ДанныеДоверенности.ДоверительФЛ_ОГРН);
			ЗаписьXML.ЗаписатьКонецЭлемента();

		Иначе

			ТекстОшибки = НСтр("ru = 'Не поддерживается отзыв с типом доверителя:'") + ДанныеДоверенности.ТипОрганизации;
			ВызватьИсключение ТекстОшибки;

		КонецЕсли;
	КонецЕсли;
	
	ЗаписьXML.ЗаписатьКонецЭлемента();
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
	ЗаписьXML.ЗаписатьКонецЭлемента();
	ЗаписьXML.ЗаписатьКонецЭлемента();
	
	
	Если Доверенность.ДляНалоговыхОрганов Тогда
		
		Префикс = "ON_OFFDOVER";
		ДатаФормирования = Формат(ТекущаяДатаСеанса(), "ДФ=yyyyMMdd;");
		ИдентификационныйНомер = Доверенность.НомерДоверенности;
		
		Получатель = XMLСтрока(Доверенность.КодНалоговогоОрганаПредставления);
		КонечныйПолучатель = Получатель;
		Если Доверенность.НалоговыеОрганыДействия.Количество() = 1 Тогда
			КонечныйПолучатель = XMLСтрока(Доверенность.НалоговыеОрганыДействия[0].КодНалоговогоОргана);
		КонецЕсли;
		
		ОписанияДоверителей = Доверенность.Доверители.НайтиСтроки(Новый Структура("ИдентификаторРодителя", 
			Новый УникальныйИдентификатор("00000000-0000-0000-0000-000000000000")));
		
		Отправитель = "";
		Для Каждого ОписаниеДоверителя Из ОписанияДоверителей Цикл
			РеквизитыДоверителя = ОписаниеДоверителя.ДоверительРеквизиты.Получить();
			Отправитель = XMLСтрока(РеквизитыДоверителя.ИНН);
			Если Не РеквизитыДоверителя.ЭтоИндивидуальныйПредприниматель И Не РеквизитыДоверителя.ЭтоФизическоеЛицо Тогда
				Отправитель = Отправитель + XMLСтрока(РеквизитыДоверителя.КПП);
			КонецЕсли;
			Прервать;
		КонецЦикла;

		
		ИмяФайла = СтрШаблон("%1_%2_%3_%4_%5_%6.xml", Префикс, Получатель, КонечныйПолучатель, Отправитель, ДатаФормирования, ИдентификационныйНомер);
	Иначе
		ИмяФайла = "revoke.xml";
	КонецЕсли;
	
	Результат = Новый Структура;
	Результат.Вставить("Содержимое", ПоместитьВоВременноеХранилище(ПолучитьДвоичныеДанныеИзСтроки(ЗаписьXML.Закрыть(), "windows-1251"), Новый УникальныйИдентификатор));
	Результат.Вставить("ИмяФайла", ИмяФайла);
	Результат.Вставить("НомерДоверенности", НомерДоверенности);
	Результат.Вставить("Доверенность", Доверенность);
	Возврат Результат; 
	
КонецФункции

Функция ИспользуетсяРежимТестирования() Экспорт
	
	Возврат Ложь;
	
КонецФункции

Функция ПараметрыРезультатаАвторизацииНаСервереМЧД()
	
	ПараметрыРезультатаАвторизации = Новый Структура;
	ПараметрыРезультатаАвторизации.Вставить("ДатаСеанса", 			Неопределено);
	ПараметрыРезультатаАвторизации.Вставить("РезультатАвторизации", Неопределено);
	Возврат ПараметрыРезультатаАвторизации;
	
КонецФункции

Функция ВладелецТикета()

	Возврат "1C-Reporting";

КонецФункции

Функция ПолучитьСтруктуруОтвета(ОтветHTTP)
	
	ТелоОтвета = ОтветHTTP.ПолучитьТелоКакСтроку();
	Если ОтветHTTP.Заголовки["Content-Type"] = "text/html" Тогда
		ФорматированныйДокумент = Новый ФорматированныйДокумент;
		ФорматированныйДокумент.УстановитьHTML(ТелоОтвета, Новый Структура);
		ФорматированнаяСтрока = ФорматированныйДокумент.ПолучитьФорматированнуюСтроку();
		СтруктураОтвета = Новый Структура("title", ФорматированнаяСтрока);
	Иначе
		СтруктураОтвета = ОбщегоНазначения.JSONВЗначение(ОтветHTTP.ПолучитьТелоКакСтроку(),,Ложь)
	КонецЕсли;
	
	Возврат СтруктураОтвета;
КонецФункции

// Используется для инициализации параметра сеанса в рамках механизмов БСП
// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииОбработчиковУстановкиПараметровСеанса.
//
Процедура УстановитьПараметрСеансаПараметрыАвторизацииВРаспределенномРеестре(
		ИмяПараметра = Неопределено,
		УстановленныеПараметры = Неопределено) Экспорт
	
	Если ИмяПараметра = "ПараметрыАвторизацииВРаспределенномРеестре" Тогда
		ПараметрыРезультатаАвторизации = ПараметрыРезультатаАвторизацииНаСервереМЧД();
		ПараметрыСеанса.ПараметрыАвторизацииВРаспределенномРеестре = Новый ФиксированнаяСтруктура(ПараметрыРезультатаАвторизации);
		УстановленныеПараметры.Добавить("РезультатАвторизацииАвторизацииНаСервереМЧДРРСКО");
	КонецЕсли;
	
КонецПроцедуры

Процедура УстановитьСтатусРегистрации(Доверенность, ИдентификаторТранзакции = Неопределено, ЭтоОтмена = Ложь) Экспорт
	ЗаписьСтатуса = РегистрыСведений.МашиночитаемыеДоверенностиСтатусы.СоздатьМенеджерЗаписи();
	ЗаписьСтатуса.МашиночитаемаяДоверенность = Доверенность;
	ЗаписьСтатуса.Прочитать();	
	ЗаписьСтатуса.МашиночитаемаяДоверенность = Доверенность;
	ЗаписьСтатуса.ДатаТранзакции = ТекущаяДатаСеанса();
	ЗаписьСтатуса.ИдентификаторТранзакции = ИдентификаторТранзакции;
	Если ЭтоОтмена Тогда
		ЗаписьСтатуса.ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.РегистрацияОтмены;
		ЗаписьСтатуса.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Отмена;
	Иначе
		ЗаписьСтатуса.ТехническийСтатус = Перечисления.ТехническиеСтатусыМЧД.Регистрация;
		ЗаписьСтатуса.ТипТранзакции = Перечисления.ТипыТранзакцийСРеестромМЧД.Регистрация;
	КонецЕсли;
	ЗаписьСтатуса.Записать();
КонецПроцедуры

Процедура ПриИзмененииСтатусаДоверенности(ИзменившиесяСтатусы) Экспорт
	Результат = Новый Структура;
	Результат.Вставить("ИмяСобытия", "ПриИзмененииСтатусаДоверенности");
	Результат.Вставить("Контекст", ИзменившиесяСтатусы);
	СерверныеОповещения.ОтправитьСерверноеОповещение("СтандартныеПодсистемы.МашиночитаемыеДоверенности", Результат, Неопределено);
КонецПроцедуры

#КонецОбласти

#КонецОбласти
